用Scrapy开发项目时遇到的问题

一. Scrapy

  • 各种依赖库的安装请提前参考官方文档 http://doc.scrapy.org/en/0.24/intro/install.html , 另外python-dev完整的开发库最好安装, 可以避免很多不知所以然的问题.
  • 如果看英文文档有困难, 可以先参看一下scrapy中文翻译项目  http://scrapy-chs.readthedocs.org/zh_CN/latest/
  • scrapy.contrib.spiders.Rule中的一些提取规则是以正则表达式形式写出, 注意网站中的". ?"等符号要进行转义. eg.
  • Rule(LinkExtractor(allow = ( " https://bitcointalk\.org/index\.php\?board=\d+\.\d+ ", ) ) )

二. scrapy 调试

scrapy本身提供了很好用的交互式调试命令,可以方便调试爬虫的各种功能。

  • 命令格式:scrapy shell url
  • 注意事项:
    • shell 命令可以需要project,也可以不需要project,当然我们调试的时候如果不是刚刚使用scrapy,肯定是为了调试自己project中的某个功能,这是就需要你在你的project目录下使用此命令,如果你的url符合当前project的domin,scrapy会自动调用你的spider,此时的交互式python命令行下的全局变量spider就是你自己编写的spider。
    • 因为scrapy shell 命令是在iinux下的命令,如果网址中包括比较特殊的符号,记得进行转义,比如 “&” 符号。
    • 进入python交互命令中,可以用dir(spider),查看spider中的各种属性,这其中就包括了你自己定义的提取函数,规则等等。
    • 注意利用view(response)在浏览器中观察爬虫看到的网页是否和我们看到的网页一样,其实大部分都是不相同的。
    • 未完待续。。。 (有时间会写一篇详细的图文调试过程)

三. 动态网页爬取的一点,动态url的处理

在爬取 https://bitsharestalk.org 的时候,发现网站会为每一个url增加一个sessionid属性,可能是为了标记用户访问历史,而且这个seesionid随着每次访问都会动态变化,这就为爬虫的去重处理(即标记已经爬取过的网站)和提取规则增加了难度。

比如 https://bitsharestalk.org/index.php?board=5.0 会变成 https://bitsharestalk.org/index.phpPHPSESSID=9771d42640ab3c89eb77e8bd9e220b53&board=5.0,下面介绍集中处理方法

    1. 仅适用你的爬虫使用的是 scrapy.contrib.spiders.CrawlSpider, 在这个内置爬虫中,你提取url要通过Rule类来进行提取,其自带了对提取后的url进行加工的函数。

    rules =  (

    Rule(LinkExtractor(allow = ( " https://bitsharestalk\.org/index\.php\?PHPSESSID\S*board=\d+\.\d+$ " ,  " https://bitsharestalk\.org/index\.php\?board=\d+\.\d+$ " )), process_links =  ' link_filtering ' ),   #默认函数process_links

    Rule(LinkExtractor(allow = ( " https://bitsharestalk\.org/index\.php\?PHPSESSID\S*topic=\d+\.\d+$ " ,  " https://bitsharestalk\.org/index\.php\?topic=\d+\.\d+$ " , ),),

    callback =  " extractPost " ,

    follow = True, process_links =  ' link_filtering ' ),

    Rule(LinkExtractor(allow = ( " https://bitsharestalk\.org/index\.php\?PHPSESSID\S*action=profile;u=\d+$ " ,  " https://bitsharestalk\.org/index\.php\?action=profile;u=\d+$ " , ),),

    callback =  " extractUser " , process_links =  ' link_filtering ' )

    )

    def link_filtering(self, links):

    ret = []

    for link  in links:

    url = link.url

    # print "This is the yuanlai ", link.url 
    urlfirst, urllast = url.split( " ? " )

    if urllast:

    link.url = urlfirst +  " ? " + urllast.split( " & " , 1)[1]

    # print link.url

    return

    links

    link_filtering()函数对url进行了处理,过滤掉了sessid,关于Rule类的process_links函数和links类,官方文档中并没有给出介绍,给出一个参考https://groups.google.com/forum/#!topic/scrapy-users/RHGtm_2GO1M(也许需要梯子,你懂得)

    如果你是自己实现的爬虫,那么url的处理更是可定制的,只需要自己处理一下就可以了。

    2.通用方法,修改scrapy的去重策略,直接用自己的算法替代内置算法。或者编写自己的scheduler中间件,这一部分笔者没有亲自实现,应该是版本更新,

    scrapy这方面有改动,读者可以自行探索。参考连接:  http://blog.pluskid.org/?p=381

四. Xpath--大多是scrapy response 自集成的xpath特性

  •  传送门  http://www.w3.org/TR/xpath20/
  • 在使用chrome等浏览器自带的提取extract xpath路径的时候, 通常现在的浏览器都会对html文本进行一定的规范化, 导致明明在浏览器中提取正确, 却在程序中返回错误的结果,比如
  • < table  cellpadding ="0"  cellspacing ="0"  border ="0"  style ="margin-left: 10px;">

    < tbody >

    some others

    </ tbody >

    </

    table>

    浏览器会在table标签下添加tbody

  • 目前本人还没有什么好的解决方法, 暂时的解决方案是, 多用相对路径或者是属性标签等定位而不依赖于绝对路径, 如果非要使用绝对路径的方法:
    • scrapy shell somepage
    • view(response)
    • 然后再开发者工具中看的路径就是原始路径
  • xpath方法extract()返回的都是unicode字符串, 要注意对其进行的操作, 以及适时转化为字符串形式(通常情况下函数会自动帮助你转换, 如果可以转换的话), 尤其是在一起使用 正则表达式 的时候会产生命名规则正确却匹配不到的情况.
  • 如果在某个xpath对象下继续使用xpath规则提取, 当提取某个对象下的所有某个对象所有tr标签.
  • html = response.xpath( " /html/body " )

    tr = html.xpath( " .//tr " )  #

    搜索body下的所有tr必须加上'.', 否则搜索的是整个文档的所有tr

五. unicode导入到json文件

使用下载器中间件即可,详情参考代码吧。(有时间详细补充)

ps: 吐槽一下排版,博客排版一直没找到什么好的工具,只能在网页版排了,不知道各位能不能推荐一下 -_-||, 拒绝任何形式的转载。

另外关于Xpath的问题可以参考http://www.educity.cn/wenda/5583.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值