一 代码区结构
def on_start(self)
是脚本的入口点。单击run
仪表板上的按钮时将调用它。self.crawl(url, callback=self.index_page)
*是这里最重要的API。它将添加一个要爬网的新任务。大多数选项将通过self.crawl
参数进行spicified 。def index_page(self, response)
得到一个Response
*对象。response.doc
*是一个pyquery对象,它具有类似jQuery的API来选择要提取的元素。def detail_page(self, response)
返回一个dict
对象作为结果。结果将resultdb
默认捕获。您可以覆盖on_result(self, result)
方法来自行管理结果。
您可能想知道的更多内容:
@every(minutes=24*60, seconds=0)
*是告诉调度程序on_start
应该每天调用方法的帮助程序。@config(age=10 * 24 * 60 * 60)
*指定页面类型的默认age
参数(when )。参数*可以通过(最高优先级)和(最低优先级)指定。self.crawl
index_page
callback=self.index_page
age
self.crawl(url, age=10*24*60*60)
crawl_config
age=10 * 24 * 60 * 60
* tell scheduler会在10天内抓取该请求。pyspider默认情况下不会抓取同一个URL两次(永远丢弃),即使你修改了代码,对于第一次运行项目并修改它并第二次运行它的初学者来说很常见,它不会再次爬行(阅读itag
解决方案)@config(priority=2)
*标记应首先抓取详细信息页面。
二 配置启动文件
新建 '''db.json''' 配置文件,文件中
{ "taskdb": "mysql+taskdb://username:password@host:port/taskdb", "projectdb": "mysql+projectdb://username:password@host:port/projectdb", "resultdb": "mysql+resultdb://username:password@host:port/resultdb", "message_queue": "amqp://username:password@host:port/%2F", "webui": { "username": "some_name", "password": "some_passwd", "need-auth": true } }
启动配置
pyspider --config db.json all
三 使用PhantomJS(自动执行js文件加载页面)
当连接PhantomJS的pyspider时,您可以通过添加参数fetch_type='js'
来启用此功能self.crawl.
class Handler(BaseHandler): def on_start(self): self.crawl('http://www.twitch.tv/directory/game/Dota%202', fetch_type='js', callback=self.index_page)
页面执行js代码
滑动滑动条,加载整个数据
class Handler(BaseHandler): def on_start(self): self.crawl('http://www.pinterest.com/categories/popular/', fetch_type='js', js_script=""" function() { window.scrollTo(0,document.body.scrollHeight); } """, callback=self.index_page)
四 pypider 爬虫结构
调度器:
调度程序从处理器的newtask_queue接收任务。确定任务是新任务还是需要重新爬网。根据优先级对任务进行排序,并将其提供给具有流量控制的提取器(令牌桶算法)。处理定期任务,丢失任务和失败的任务,然后重试。
提取器
Fetcher负责获取网页,然后将结果发送给处理器。对于灵活的,fetcher支持数据URI和由JavaScript呈现的页面(通过phantomjs)。可以通过API通过脚本控制获取方法,标头,cookie,代理,etag等。
处理器
处理器负责运行用户编写的脚本来解析和提取信息。您的脚本在无限制的环境中运行。虽然我们有各种工具(如PyQuery)可供您提取信息和链接,但您可以使用任何想要处理响应的内容。
执行流程
on_start
当您按下Run
WebUI上的按钮时,每个脚本都有一个名为callback的回调。将新任务on_start
作为项目条目提交给Scheduler。
- Scheduler将此
on_start
任务调度为数据URI作为Fetcher的常规任务。
- Fetcher发出请求并对其做出响应(对于数据URI,这是一个虚假的请求和响应,但与其他正常任务没有区别),然后提供给处理器。
- 处理器调用该
on_start
方法并生成一些新的URL以进行爬网。处理器向Scheduler发送一条消息,告知此任务已完成,新任务通过消息队列发送到Scheduler(on_start
在大多数情况下,这里没有结果。如果有结果,则处理器将它们发送给result_queue
)。
- 调度程序接收新任务,在数据库中查找,确定任务是新的还是需要重新爬网,如果是,则将它们放入任务队列。按顺序发送任务。
- 这个过程重复(从第3步开始)并且在WWW死亡之前不会停止;-)。调度程序将检查定期任务以爬网最新数据。
五 self.crawl API
@config(age=10 * 24 * 60 * 60) 任务有效期
priority=1 优先级
exetime=time.time()+30*60 任务执行时间
auto_recrawl = True 自动爬取
params={'a': 123, 'b': 'c'} GET请求参数
method='POST' 请求方式 默认为GET
data={'a': 123, 'b': 'c'} post方式提交数据
{field: {filename: 'content'}} 分段执行文件
User-Agent ='Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36 '
timeout=' '
allow_redirects=True 默认为false
fetch_type='js' 启用JavaScript fetcher
js_script=''' function() { window.scrollTo(0,document.body.scrollHeight); return 123; } ''' 在页面加载之前或之后运行的JavaScript
load_images 默认False
使用示例
def on_start(self): self.crawl('http://www.example.org/', callback=self.callback, age=5*60*60, auto_recrawl=True)
#get请求携带参数 def on_start(self): self.crawl('http://httpbin.org/get', callback=self.callback, params={'a': 123, 'b': 'c'}) self.crawl('http://httpbin.org/get?a=123&b=c', callback=self.callback)
#post请求携带参数 def on_start(self): self.crawl('http://httpbin.org/post', callback=self.callback, method='POST', data={'a': 123, 'b': 'c'})
#加在页面加载之前或之后运行的JavaScript def on_start(self): self.crawl('http://www.example.org/', callback=self.callback, fetch_type='js', js_script=''' function() { window.scrollTo(0,document.body.scrollHeight); return 123; } ''')
五 全局请求参数
class Handler(BaseHandler): crawl_config = { 'headers': { 'User-Agent': 'GoogleBot', } 'proxy': 'localhost:8080' } ...
六 response 对象
Response.url 返回最终的url
Response.text返回最终的文本
Response.content 响应内容,以字节为单位。
Response.doc
一个PyQuery响应的内容的对象。链接默认为绝对链接。
请参阅PyQuery的文档:https://pythonhosted.org/pyquery/
Response.etree 一个LXML响应的内容的对象。
Response.json 响应的JSON编码内容(如果有)。