第8章 scrapy进阶开发(2)
8-4 selenium集成到scrapy中
其实也没什么好说的直接上代码
这是在middlewares.py中定义的一个class:
from selenium.common.exceptions import TimeoutException
from scrapy.http import HtmlResponse #传递js加载后的源代码,不会返回给download
class JSPageMiddleware(object):
#通过chrome请求动态网页
def process_request(self, request, spider):
if spider.name == "JobBole":
try:
spider.browser.get(request.url)
except TimeoutException:
print('30秒timeout之后,直接结束本页面')
spider.browser.execute_script('window.stop()')
import time
time.sleep(3)
print("访问:{0}".format(request.url)) return HtmlResponse(url=spider.browser.current_url, body=spider.browser.page_source, encoding="utf-8", request=request)
'''编码默认是unicode'''
spider中的代码:
name = "JobBole"
allowed_domains = ["jobbole.com"]
start_urls = ['http://blog.jobbole.com/all-posts/'] def __init__(self):
'''chrome放在spider中,防止每打开一个url就跳出一个chrome'''
self.browser=webdriver.Chrome(executable_path='E:/chromedriver.exe')
self.browser.set_page_load_timeout(30)
super(JobboleSpider, self).__init__()
dispatcher.connect(self.spider_close,signals.spider_closed) def spider_close(self,spider):
#当爬虫退出的时候关闭Chrome
print("spider closed")
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上运行):
from pyvirtualdisplay import Display
display = Display(visible=0, size=(800, 600))
display.start() browser = webdriver.Chrome()
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信号量的代码):
#收集伯乐在线所有404的url以及404页面数
handle_httpstatus_list = [404] def __init__(self, **kwargs):
self.fail_urls = []
dispatcher.connect(self.handle_spider_closed, signals.spider_closed) def handle_spider_closed(self, spider, reason):
self.crawler.stats.set_value("failed_urls", ",".join(self.fail_urls)) def parse(self, response):
"""
1. 获取文章列表页中的文章url并交给scrapy下载后并进行解析
2. 获取下一页的url并交给scrapy进行下载, 下载完成后交给parse
"""
#解析列表页中的所有文章url并交给scrapy下载后并进行解析
if response.status == 404:
self.fail_urls.append(response.url)
self.crawler.stats.inc_value("failed_url") post_nodes = response.css("#archive .floated-thumb .post-thumb a")
for post_node in post_nodes:
image_url = post_node.css("img::attr(src)").extract_first("")
post_url = post_node.css("::attr(href)").extract_first("")
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
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
觉得好就点个推荐吧!
第8章 scrapy进阶开发(2)的更多相关文章
- 第8章 scrapy进阶开发(1)
		
8-1 selenium动态网页请求与模拟登录知乎 Ⅰ.介绍selenium 1.什么是selenium:selenium百度百科 2.selenium的构架图: 如果要操作浏览器,还需要一个driv ...
 - 【odoo14】第十三章、网站开发(对外服务)
		
本章我们将介绍一些关于odoo web服务方面的基础知识.进阶的内容,将在第十四章介绍. odoo中的web请求是由python的werkzeug库驱动的.odoo为了操作方便,对werkzeug进行 ...
 - 【SharePoint学习笔记】第1章 SharePoint Foundation开发基础
		
SharePoint Foundation开发基础 第1章 SharePoint Foundation开发基础 SharePoint能做什么 企业信息门户 应用程序工具集(文档库.工作空间.工作流.维 ...
 - SharePoint 2010 最佳实践学习总结------第1章 SharePoint Foundation开发基础
		
----前言 这段时间项目出在验收阶段,不是很忙,就潜心把SharePoint学一下,不求有多深刻,初衷只是先入门再说.后续会发布一系列的学习总结.主要学习的书籍为<SharePoint2010 ...
 - 第一章 搭建Qt开发环境
		
第一章 搭建Qt开发环境 1.到http://download.qt-project.org/archive/上下载Qt的源码包.我下载的是qt-everywhere-opensource-src-4 ...
 - 编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则)
		
编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则) 目录 建议1: 不要在常量和变量中出现易混淆的字母 建议2: 莫让常量蜕变成变量 建议3: 三元操作符的类型务 ...
 - Android群英传笔记——第二章:Android开发工具新接触
		
Android群英传笔记--第二章:Android开发工具新接触 其实这一章并没什么可讲的,前面的安装Android studio的我们可以直接跳过,如果有兴趣的,可以去看看Google主推-Andr ...
 - 【STM32H7教程】第2章    STM32H7的开发环境搭建
		
完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第2章 STM32H7的开发环境搭建 本章主要为大 ...
 - 第三百九十四节,Django+Xadmin打造上线标准的在线教育平台—Xadmin后台进阶开发配置2,以及目录结构说明
		
第三百九十四节,Django+Xadmin打造上线标准的在线教育平台—Xadmin后台进阶开发配置2,以及目录结构说明 设置后台列表页面可以直接修改字段内容 在当前APP里的adminx.py文件里的 ...
 
随机推荐
- leetcode 有效的字母异位词
			
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的一个字母异位词. 示例 1: 输入: s = "anagram", t = "nagaram" ...
 - ES6——Class的继承
			
class 的继承和使用. 子类继承父类,使用extends关键字. 为父类知道那个静态方法,使用 static方法名字super: 在构造函数中,可以当一个函数来使用,相当于调用父类的构造函数. 在 ...
 - UWP开发入门(四)——自定义CommandBar
			
各位好,再次回到UWP开发入门系列,刚回归可能有些不适应,所以今天我们讲个简单的,自定义CommandBar,说通俗点就是自定义类似AppBarButton的东西,然后扔到CommandBar中使用. ...
 - Web Api 内部数据思考 和 利用http缓存优化 Api
			
在上篇<Web Api 端点设计 与 Oauth>后,接着我们思考Web Api 的内部数据: 其他文章:<API接口安全加强设计方法> 第一 实际使用应该返回怎样的数据 ? ...
 - D - How Many Tables (并查集)(水题)
			
点击打开链接 Today is Ignatius' birthday. He invites a lot of friends. Now it's dinner time. Ignatius want ...
 - LOJ#6045. 「雅礼集训 2017 Day8」价(最小割)
			
题面 传送门 题解 首先先把所有权值取个相反数来求最大收益,因为最小收益很奇怪 然后建图如下:\(S\to\)药,容量\(\inf+p_i\),药\(\to\)药材,容量\(\inf\),药材\(\t ...
 - 【bug】—— H5页面在 ios 端滑动不流畅的问题
			
IOS系统的惯性滑动效果非常6,但是当我们对div加overflow-y:auto;后是不会出这个效果的,滑动的时候会感觉很生涩.怎么办? 方案一: 在滚动容器内加-webkit-overflow-s ...
 - SpringBoot idea maven打包war及运行war包
			
pom.xml修改打包类型pom改为war <artifactId>Test02</artifactId> <packaging>war</packaging ...
 - python 爬虫 黑科技
			
1.最基本的抓站 import urllib2 content = urllib2.urlopen('http://XXXX').read() 2.使用代理服务器 这在某些情况下比较有用,比如IP被封 ...
 - POJ 2239
			
#include<iostream> #include<algorithm> #define MAXN 305 using namespace std; int _m[MAXN ...