• 第8章 scrapy进阶开发(2)


    8-4 selenium集成到scrapy中

    其实也没什么好说的直接上代码

    这是在middlewares.py中定义的一个class:

     1 from selenium.common.exceptions import TimeoutException
     2 from scrapy.http import HtmlResponse  #传递js加载后的源代码,不会返回给download
     3 class JSPageMiddleware(object):
     4     #通过chrome请求动态网页
     5     def process_request(self, request, spider):
     6         if spider.name == "JobBole":
     7             try:
     8                 spider.browser.get(request.url)
     9             except TimeoutException:
    10                 print('30秒timeout之后,直接结束本页面')
    11                 spider.browser.execute_script('window.stop()')
    12             import time
    13             time.sleep(3)
    14             print("访问:{0}".format(request.url))
    15 
    16             return HtmlResponse(url=spider.browser.current_url, body=spider.browser.page_source, encoding="utf-8", request=request)
    17             '''编码默认是unicode'''

    spider中的代码:

     1     name = "JobBole"
     2     allowed_domains = ["jobbole.com"]
     3     start_urls = ['http://blog.jobbole.com/all-posts/']
     4 
     5     def __init__(self):
     6         '''chrome放在spider中,防止每打开一个url就跳出一个chrome'''
     7         self.browser=webdriver.Chrome(executable_path='E:/chromedriver.exe')
     8         self.browser.set_page_load_timeout(30)
     9         super(JobboleSpider, self).__init__()
    10         dispatcher.connect(self.spider_close,signals.spider_closed)
    11 
    12     def spider_close(self,spider):
    13         #当爬虫退出的时候关闭Chrome
    14         print("spider closed")
    15         self.browser.quit()

    把selenium集成到scrapy中主要改变的就是这两处地方。

    以上的在scrapy中嵌入selenium的chrome并不是异步的,所以效率会变差。

    这里都是部分代码,完整代码链接https://github.com/pujinxiao/jobbole_spider

    8-5 其余动态网页获取技术介绍-chrome无界面运行、scrapy-splash、selenium-grid, splinter 

    1.chrome无界面运行

    主要是以下代码(不能在windows上运行):

    1 from pyvirtualdisplay import Display
    2 display = Display(visible=0, size=(800, 600))
    3 display.start()
    4 
    5 browser = webdriver.Chrome()
    6 browser.get()

    2.scrapy-splash

    Splash是一个Javascript渲染服务。它是一个实现了HTTP API的轻量级浏览器,Splash是用Python实现的,同时使用Twisted和QT。Twisted(QT)用来让服务具有异步处理能力,以发挥webkit的并发能力。

    可以在scrapy中处理ajax来抓取动态的数据,没有chrome那么稳定。

    更多介绍 传送门

    3.selenium-grid(自行百度查看)

    4.splinter

    8-6 scrapy的暂停与重启

    在命令行:scrapy crawl lagou -s JOBDIR=job_info/001 

    只要按一次 ctrl+c 就会暂停爬虫,重新启动一样的命令再运行一边。

    会生成以下文件:

    在requests.queue文件中有以下文件:

    如果要保存在不同的文件那就修改不同路径就好了,spider会重新从第一个url开始爬取。

    8-7 scrapy url去重原理

    相关代码都在dupefilter.py中

    其实就是做了一个哈希摘要,放在set中,去查新的url是否在set中。

    8-8 scrapy telnet服务

    详细的介绍在scrapy文档中都有,传送门

    你可以在cmd中监听spider中的变量。先要在控制面板中打开telnet客户端和服务端,在cmd中输入 telnet localhost 6023 即可。

    但是不知道为什么,win10中没有telnet服务端,而且我打开telnet的后不能输入字母(待解决)

    8-9 spider middleware 详解

    平时也没怎么用到,理解的也不够透彻。scrapy的中文文档中也写的很详细,传送门,大家可以参考。

    主要是这么几个文件:

    depth.py:爬取深度的设置

    httperror.py:状态的设置,比如是不是要把404的也抓取下来,等等。

    其他的话自己了解把,需要的时候在深入了解做下笔记。

    8-10 scrapy的数据收集 和 8-11 scrapy信号详解

    文档说明,数据收集传送门。在工作中没有用到,用到了再细写,这样理解更好。

    scrapy信号是非常重要的,之前在selenium中chrome就是用信号量,当spider关闭时,再关闭chrome。信号量详解传送门

    实例就是伯乐在线的例子:

    部分代码如下(可以借鉴,其实也包含了8-11信号量的代码):

     1 #收集伯乐在线所有404的url以及404页面数
     2     handle_httpstatus_list = [404]
     3 
     4     def __init__(self, **kwargs):
     5         self.fail_urls = []
     6         dispatcher.connect(self.handle_spider_closed, signals.spider_closed)
     7 
     8     def handle_spider_closed(self, spider, reason):
     9         self.crawler.stats.set_value("failed_urls", ",".join(self.fail_urls))
    10 
    11     def parse(self, response):
    12         """
    13         1. 获取文章列表页中的文章url并交给scrapy下载后并进行解析
    14         2. 获取下一页的url并交给scrapy进行下载, 下载完成后交给parse
    15         """
    16         #解析列表页中的所有文章url并交给scrapy下载后并进行解析
    17         if response.status == 404:
    18             self.fail_urls.append(response.url)
    19             self.crawler.stats.inc_value("failed_url")
    20 
    21         post_nodes = response.css("#archive .floated-thumb .post-thumb a")
    22         for post_node in post_nodes:
    23             image_url = post_node.css("img::attr(src)").extract_first("")
    24             post_url = post_node.css("::attr(href)").extract_first("")
    25             yield Request(url=parse.urljoin(response.url, post_url), meta={"front_image_url":image_url}, callback=self.parse_detail)

    全部代码移步github:https://github.com/pujinxiao/jobbole_spider/blob/master/bole/spiders/JobBole.py

    结果: (错误的url也被统计记录下来了)

    8-12 scrapy扩展开发

    扩展之间看文档,传送门

    作者:今孝
    出处:http://www.cnblogs.com/jinxiao-pu/p/6815845.html
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

    觉得好就点个推荐吧!

  • 相关阅读:
    28.数组中出现次数超过长度一半的数字(python)
    [leetcode] 145. 二叉树的后序遍历
    [leetcode] 144. 二叉树的前序遍历
    [leetcode] 94. 二叉树的中序遍历
    [leetcode] 93. 复原IP地址
    [leetcode] 206. 反转链表
    [leetcode] 92. 反转链表 II
    [leetcode] 91. 解码方法
    [leetcode] 90. 子集 II.md
    [leetcode] 88. 合并两个有序数组
  • 原文地址:https://www.cnblogs.com/jinxiao-pu/p/6815845.html
Copyright © 2020-2023  润新知