scrapy爬虫: https:www.scrapy.org

本篇博客依托的项目: https://github.com/viciousstar/BitcointalkSpider/

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

Scrapy使用以及Xpath的一些坑, 再入剁手的更多相关文章

  1. 浅谈Android Studio3.0更新之路(遇坑必入)

    >可以参考官网设置-> 1 2 >> Fantasy_Lin_网友评论原文地址是:简书24K纯帅豆写的我也更新一下出处[删除]Fa 转自脚本之家 浅谈Android Studi ...

  2. Keil C51 中的函数指针和再入函数

    函数指针是C语言中几个难点之一.由于8051的C编译器的独特要求,函数指针和再入函数有更多的挑战需要克服.主要由于函数变量的传递.典型的(绝大部分8051芯片)函数变量通过堆栈的入栈和出栈命令来传递. ...

  3. 关于在scrapy中使用xpath

    1. 还是以虎嗅为例,他给我返回的是一个json格式的json串 2.那么我需要操作的就是把json串转换成我们的字典格式再进行操作 str=json.loads(response.body)['da ...

  4. scrapy初体验 - 安装遇到的坑及第一个范例

    scrapy,python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据.scrapy用途广泛,可以用于数据挖掘.监测和自动化测试.scrapy的安装稍 ...

  5. #0 scrapy爬虫学习中遇到的坑记录

    python 基础学习中对于scrapy的使用遇到了一些问题. 首先进行的是对Amazon.cn的检索结果页进行爬取,很顺利,无碍. 下一个目标是对baidu的搜索结果进行爬取 1,反爬虫 1.1 我 ...

  6. pycharm创建scrapy项目教程及遇到的坑

    最近学习scrapy爬虫框架,在使用pycharm安装scrapy类库及创建scrapy项目时花费了好长的时间,遇到各种坑,根据网上的各种教程,花费了一晚上的时间,终于成功,其中也踩了一些坑,现在整理 ...

  7. scrapy python2升级python3遇到的坑

    换成Python3首先pycharm先执行: 然后看代码自己所需要的第三方库都要重新装 然后执行代码: 遇到这样的错如下: SyntaxError: invalid syntax 先检查print 所 ...

  8. Scrapy解析器xpath

    一.使用xpath 不在scrapy框架中通过response from scrapy.http import HtmlResponse HtmlResponse->TextResponse-& ...

  9. [ 转 ] scrapy 中解决 xpath 中的中文编码问题

    1.问题描述: 实现定位<h2>品牌</h2>节点 brand_tag = sel.xpath("//h2[text()= '品牌']") 报错:Value ...

随机推荐

  1. Andriod视频http://pan.baidu.com/share/link?shareid=7300&uk=3339495714

    老罗Android开发 视频教程           一.Android入门介绍 视频教程     1.1 android系统介绍   1.3 如何搭建android开发环境   1.5 androi ...

  2. 安装 macbook 双系统( OS X 和 Ubuntu )

    打算 macbook 上面多安装一个 ubuntu 系统来用下.流程大致下面几步: 1. 备份重要资料 2. 划分硬盘区域用于安装 ubuntu 3. 下载 ubuntu ISO 文件,并刻录到 U ...

  3. 上海Uber优步司机奖励政策(1月18日~1月24日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  4. Finding Palindromes - 猥琐的字符串(Manacher+trie)

    题目大意:有 N 个字符串,所有的字符串长度不超过 200W 任意俩俩字符串可以自由组合,问组合的字符串是回文串的个数有多少个?   分析:这是一个相当猥琐的字符串处理,因为没有说单个的字符串最少多长 ...

  5. 跨平台通信中间件thrift学习【Java版本】(转)

    转自:http://neoremind.com/2012/03/%E8%B7%A8%E5%B9%B3%E5%8F%B0%E9%80%9A%E4%BF%A1%E4%B8%AD%E9%97%B4%E4%B ...

  6. Dijkstra算法为什么权值不能为负

    Dijkstra算法当中将节点分为已求得最短路径的集合(记为S)和未确定最短路径的个集合(记为U),归入S集合的节点的最短路径及其长度不再变更,如果边上的权值允许为负值,那么有可能出现当与S内某点(记 ...

  7. 性能比较工具runstats

    runstats能对做同一件事的两个不同方法进行比较,得出谁好一点.我们只需要提供两个不同方法,余下的事情都由runstats负责.runstats只是测量3个要素: 1. 耗用的时间. 2. 系统统 ...

  8. Android系统默认Home应用程序(Launcher)的启动过程源码分析

    在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还须要有一个Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home应 ...

  9. Linux 下实现控制屏幕显示信息和光标的状态

    //display.h /************************************************************* FileName : display.h File ...

  10. CALayer的基本操作

     CALayer简介:   CALayer又称为层. 在每一个UIView内部都有一个Layer这样的属性. UIView之所以能够显示,就是因为它里面有这个一个层,才具有显示的功能. 我们通过操作C ...