首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python 学习手册
Python Cookbook
Python 基础教程
Python Sites
PyPI - Python Package Index
http://www.simple-is-better.com/
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
V2EX  ›  Python

关于爬虫的一些问题

  •  
  •   LINAICAI · 2014-12-30 10:55:05 +08:00 · 3446 次点击
    这是一个创建于 1802 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在学习Python,尝试爬一些站,发现有些站并不好爬,不是因为分页问题,这个还算好迭代。下面列举一下:
    1、某些站正文内容是用<p></p>这种方法把一段文字分成几行,另外图片和时间的字段也是用<p></p>装饰,正则不会写。
    2、爬站的时候虽然用单线程,但明显感觉到网站对于爬虫有一个访问限制,爬一页需要的时间居然很固定在10秒左右。
    3、单线程下爬完一页应该上传到我的远程数据库,但如果遇到上传过程中产生错误或者异常,那么一页爬的数据并没有全部上传完毕,这时候用多线程就麻烦了,很可能不清楚上传进度,单线程下因为异常退出没有办法做到全自动。

    想请教一下高手怎么破啊,这些问题。

    35 回复  |  直到 2015-01-02 15:57:45 +08:00
        1
    wuhang89   2014-12-30 11:21:08 +08:00   ♥ 1
    你需要解析HTML库BeautifulSoup,易于使用的http链接库requests,貌似你程序架构设计有问题,但是你没有列举清楚,所以无法帮助你。
        2
    XadillaX   2014-12-30 11:41:53 +08:00   ♥ 1
    用 PyQuery 吧。
        3
    LINAICAI   2014-12-30 11:42:56 +08:00
    @wuhang89
    # <DIV class=align_entry_hack><p><img src="http://imgout.ph.126.net/39099091/molecula_lamp_02.jpg" alt="" /></p><p>&ldquo;Molecula&rdquo;是一个功能性灯具,它可以是台灯,也可以安装在墙壁的壁灯,它不仅仅是灯具,还是一个线条明快的雕塑。</p><p>&ldquo;Molecula&rdquo;白天可以是雕塑,装饰家居环境,晚上就是照明的灯具,内置超薄的LED 灯条,完美的隐藏在灯架内。...</p></DIV>
    # <table width="97%" border="0" align="center" cellpadding="0" cellspacing="0" class="di">
    # <tr>
    # <td height="26" valign="top"><div align="left">j.lee 发表于 2014年12月16日</div></td>
    # <td valign="top"><div align="right"><a href="http://www.qiqufaxian.cn/post/8055.html">详细阅读</a></div></td>
    # </tr>
    # </table>
    # </DIV>


    比如上面这段,应该怎样写正则?
    图片URL和正文什么的用几个<p></p>拼凑的
        4
    kchum   2014-12-30 11:51:16 +08:00   ♥ 1
    @LINAICAI 你需要给多几个数据,才可以判断。例如第一个 p 都是图片?或者外面的那层 div 就是一个正文容器
        5
    LINAICAI   2014-12-30 11:55:46 +08:00
    @kchum 是的,第一个p都是图片 后面正文的是不定数目的p段
        6
    LINAICAI   2014-12-30 11:57:31 +08:00
    真的想知道 为什么有这么写的站。。。
    这个是为了反爬做的措施吗
        7
    wuhang89   2014-12-30 13:53:06 +08:00   ♥ 3
    都叫你看看BeautifulSoup的文档了,做事情不要想当然的以为。
    >>> from bs4 import BeautifulSoup
    >>> html = '<DIV class=align_entry_hack><p><img src="http://imgout.ph.126.net/39099091/molecula_lamp_02.jpg" alt="" /> </p><p>“Molecula”是一个功能性灯具,它可以是台灯,也可以安装在墙壁的壁灯,它不仅仅是灯具,还是一个线条明快的雕塑。</p><p>“Molecula”白天可以是雕塑,装饰家居环境,晚上就是照明的灯具,内置超薄的LED 灯条, 完美的隐藏在灯架内。...</p></DIV><table width="97%" border="0" align="center" cellpadding="0" cellspacing="0" class="di"><tr><td height="26" valign="top"><div align="left">j.lee 发表于 2014年12月16日</div></td><td valign="top"><div align="right"><a href="http://www.qiqufaxian.cn/post/8055.html">详细阅读</a> </div></td></tr></table></DIV>'
    >>> soup = BeautifulSoup(html)
    >>> content = soup.find('div', {'class' : 'align_entry_hack'})
    >>> print(content.text)
    “Molecula”是一个功能性灯具,它可以是台灯,也可以安装在墙壁的壁灯,它不仅仅是灯具,还是一个线条明快的雕塑。“Molecula”白天可以是雕塑,装饰家居环境,晚上就是照明的灯具,内置超薄的LED 灯条,完美的隐藏在灯架内。...
        8
    LINAICAI   2014-12-30 14:48:13 +08:00
    @wuhang89 太屌!
        9
    herozzm   2014-12-30 15:21:32 +08:00   ♥ 1
    先学正则,再学爬虫
        10
    Melodic   2014-12-30 15:32:37 +08:00
    xpath的一个函数叫做descendant,可以获取该标签下的所有子节点
        11
    LINAICAI   2014-12-30 17:17:05 +08:00
    @herozzm 看一次用一次下次用忘记了。。。
        12
    wilbeibi   2014-12-30 17:29:20 +08:00
    用lxml吧~
        13
    MasterYoda   2014-12-30 17:43:44 +08:00
    xpath嘛
        14
    pandada8   2014-12-30 17:44:49 +08:00
    网页爬虫就不要用正则写吧,除非是非常有规律的网页。
        15
    herozzm   2014-12-30 17:53:58 +08:00
    @pandada8 正则适用所有情况
        16
    KentY   2014-12-30 17:59:47 +08:00
    我不常弄爬虫,但是前端时间在抓一些网上资源的时候遇到一个比较棘手的是人家服务器ban你ip请求,如果你请求过频。 这个目前是先去别的代理网站抓个代理列表,轮着爬该服务器,但是代理质量又不好保证, 又要随爬随清理,然后不够了再抓一票代理。。。 这个烦人
        17
    iannil   2014-12-30 18:40:30 +08:00
    如果是抓标题+内容这种东西的话,还是有办法的。
    标题很好拿,一个正则就搞定了,正文的话,可以把html拿到以后,逐行读取,然后获取每行的长度,基本上整个html页长度最长的行的组合就是正文。
    然后自己在做一些针对目标网站的判断,就可以把比较干净的正文摘出来了。
        18
    binux   2014-12-30 18:43:51 +08:00
        19
    pandada8   2014-12-30 19:00:47 +08:00
    @herozzm ...
        20
    alexapollo   2014-12-30 19:33:09 +08:00
        21
    herozzm   2014-12-30 21:34:18 +08:00
    @pandada8
    @binux
    正则应该是比较通用的选择吧,不管你用的是python还是golang,只是性能消耗较大
        22
    herozzm   2014-12-30 21:41:09 +08:00
    也可以用xpath和css selector
        23
    pandada8   2014-12-30 22:12:33 +08:00
    @herozzm 您老先去看了那篇stackoverflow的文章呗
    我还真是第一次看到这样的说法……
    一般来说正则性能比xpath之流要好,性能消耗也少,但是对于复杂页面结构和复杂页面内容比较无力,同时并不通用,你可能需要随时修改正则
    xpath 与 css selector 倒是显得比较通用,再加上beautifulsoup这种库的傻瓜化封装使用较为方便,但是由于要解析html,开销反而倒是比较大
        24
    mengskysama   2014-12-30 22:25:41 +08:00
    BS4确实是好东西,开销大不是开玩笑,而且有些不标准的html页面比如遇到没有进行正确转义bs4会解析出错,如果工作量很大可以考虑lxml要快要快一些。

    前端限制频率的话在前面加个GAE就行了,遇到错误重试,GAE出口是'随机'好几十个。

    第三个问题明显是设计缺陷。
        25
    herozzm   2014-12-30 22:25:43 +08:00
    @pandada8 我说正则比较通用是指的这种方式,并不是说具体匹配的写法通用,用了正则,肯定是每个页面得单独写正则
        26
    pandada8   2014-12-30 22:30:27 +08:00
    @herozzm 常见的语言应该也都不缺HTML解析的库
        27
    herozzm   2014-12-30 22:34:13 +08:00
    @pandada8 php似乎就没有,得上正则吧?
        28
    pandada8   2014-12-30 22:38:59 +08:00
        29
    herozzm   2014-12-30 22:46:17 +08:00
    @pandada8 孤陋寡闻了
        30
    fewspider   2014-12-31 00:31:53 +08:00 via Android   ♥ 1
    1、beautifulsoup可以搞定,找到那个节点后,text就是内容了
    2、10秒左右,这明显是网速,打开一个页面,加载那些数据,这些都需要时间,不是站点限制你访问
    3、可以try exception一下,把需要的数据整理一下,判断是否为空,不为空再去调数据库插入
        31
    beverse   2014-12-31 00:43:49 +08:00 via Android
    我也刚学,完全用正则,你可以看看:codejob.me

    解析很容易的,关键在于稳定把网页下载下来。
        32
    LINAICAI   2014-12-31 00:44:30 +08:00
    @fewspider
    1、新人一个确实不知道这个利器
    2、但我访问其他站甚至爬另外一个站确实比这个快的多
        33
    fewspider   2014-12-31 00:46:26 +08:00 via Android
    @LINAICAI 你可以ping一下这个站跟其他站的速度
        34
    doumeki   2014-12-31 16:19:05 +08:00
    BS4注意,之前用过,发现不能很好处理如<br>这样的自闭代码。当然如果Hack也简单,也就一句话的事。lxml也试过,不明原因的运行中每次输出的结果都不一至,估计也是<br><br>这类导致的
        35
    LINAICAI   2015-01-02 15:57:45 +08:00
    @wuhang89
    <p><img src="images/n_shiye.gif" width="151" height="268" align="left" />XXX</p>

    这个怎么获取XXX的内容,用beautifulsoup。
    soup.find('omg', {'align' : 'left'})貌似获取的只有XXX前面的标签啊。
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1174 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 31ms · UTC 23:56 · PVG 07:56 · LAX 15:56 · JFK 18:56
    ♥ Do have faith in what you're doing.