本文参照官方文档译
API 参考
- self.crawl
- Response
- self.send_message
- @every
- @catch_status_code_error
一 self.crawl(url, **kwargs)
pyspider 主要的API,用于创建一个爬取任务,url 为目标地址。
参 数
*必选参数
url: 抓取的目标地址
callback: 回调函数
def on_start(self):
self.crawl(url='http://scrapy.org/', callback=self.index_page)
*以下参数是可选的
age: 任务的有效期,以秒为单位,在有效期内,该页面被爬虫视为未修改状态,忽略抓取。默认值为-1:永久有效
@config(age=10 * 24 * 60 * 60) # 这里表示有效期为10天,既10天内不会改变
def index_page(self, response):
...
priority: 爬取优先级,数字越大优先级越大,默认为0。可以用这个来先做宽度搜索BFS并减少队列中的任务数(这可能会花费更多的内存资源)
def index_page(self):
self.crawl('http://www.example.org/page2.html', callback=self.index_page)
self.crawl('http://www.example.org/233.html', callback=self.detail_page,
priority=1)
exetime:Unix时间戳中任务的执行时间,默认为0(立即执行)
import time
def on_start(self):
self.crawl('http://www.example.org/', callback=self.callback,
exetime=time.time()+30*60) # 标识30分钟之后再执行
retries: 失败重试次数,默认:3
itag: 任务标记值,此标记会在抓取时对比,如果这个值发生改变,不管有效期有没有到都会重新抓取新内容.多数用来动态判断内容是否修改或强制重爬.默认值是:None。(如果你想重新爬取所有任务,你可以通过在Handler.crawl_config 设置itag值来重新设置新的版本号)
example1:
def index_page(self, response):
for item in response.doc('.item').items():
self.crawl(item.find('a').attr.url, callback=self.detail_page,
itag=item.find('.update-time').text()) #update-time字段值改变,则无论有效期多少,重新爬取
example1:
class Handler(BaseHandler):
crawl_config = {
'itag': 'v223'
}
auto_recrawl: 自动重爬,当设置为True时,任务每过一次有效期(age)都会自动重新爬取,默认值为False
def on_start(self):
self.crawl('http://www.example.org/', callback=self.callback,
age=5*60*60, auto_recrawl=True)
method: HTTP请求方法,默认:GET
params:URL后面的请求参数,字典
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)
#这两种请求是一样的
data: POST请求参数,字典值会form-encode后再附加
def on_start(self):
self.crawl('http://httpbin.org/post', callback=self.callback,
method='POST', data={'a': 123, 'b': 'c'})
files: 文件上传,字典类型{field: {filename: 'content'}}
user_agent: 请求user-agent
headers: 请求头,字典类型
cookies:自定义请求的cookies,字典类型
connect_timeout: 指定请求时链接超时时间,单位秒,默认值:20
timeout: 请求内容里最大等待秒数.默认值:120
allow_redirects: 遇到30x状态码时是否重新请求跟随.默认是:True
validate_cert: 遇到HTTPS类型的URL时是否验证证书,默认值:True
proxy: 设置代理服务器,格式如username:password@hostname:port
暂时只支持http代理(也可以在Handler.crawl_config
中设置全局代理)
class Handler(BaseHandler):
crawl_config = {
'proxy': 'localhost:8080'
}
etag: 页面内容没改变则使用HTTP Etag机制传递进程默认值:True
last_modified: 页面内容没改变则使用HTTP Last-Modified标机制传递进程默认值:True
fetch_type: 设置是否启用JavaScript解析引擎. default: None
js_script: 页面加载前或者加载后运行JavaScript 脚本,格式:function() { document.write("binux"); }
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;
}
''')
#在这个函数中,脚本会将页面滚动到底部。函数中返回的值可以通过Response.js_script_result来返回
js_run_at: 和上面运行js脚本js_script一起使用,可以设置运行脚本的位置在开头document-start
或是结尾document-end
,默认:document-end
js_viewport_width/js_viewport_height: JavaScript渲染页面时的窗口大小。
load_images: 当开启js fetcher时,是否读取图片,默认为False
save: save 参数非常有用,可以在不同的方法之 间传递参数,比如传递一个对象给callback函数
def on_start(self):
self.crawl('http://www.example.org/', callback=self.callback,
save={'a': 123})
def callback(self, response):
return response.save['a']
taskid: pyspider判断两个任务是否是重复 的是使用的是该任务对应的 URL 的 MD5 值作为任务的唯一ID,如果ID 相 同,那么两个任务就会判定为相同,其中一个就不会爬取了 。 很多情况下请求的链接叮能是同一个,但是POST的参数不同。 这时可以重写task_id()方法,改变这个ID的计算方式来实现不同任务的区分
import json
from pyspider.libs.utils import md5string
def get_taskid(self, task):
return md5string(task['url']+json.dumps(task['fetch'].get('data', '')))
force_update: 即使任务处于 ACTIVE状态,那也会强制更新状态
cancel: cancel是取消任务,如果一个任务是 ACTIVE状态的, 则需要将 force_update设置为 True
cURL command
self.crawl(curl_command)
cURL用于发HTTP请求命令行工具轻松获取Chrome Devtools>网络面板右键单击请求复制cURL
您使用cURL命令作第参数self.crawl解析命令并使HTTP请求像curl
如何删除任务?
将任务的 group 设置为 delete ,并将状态设置为 STOP,没有更新 24小时 之后,scheduler 会自动删除任务。
@config(**kwargs)
将修饰方法用作回调时self.crawl的默认参数。
@config(age=15*60)
def index_page(self, response):
self.crawl('http://www.example.org/list-1.html', callback=self.index_page)
self.crawl('http://www.example.org/product-233', callback=self.detail_page)
@config(age=10*24*60*60)
def detail_page(self, response):
return {...}
# 1.html的存活期为15分钟,而233页面的存活期为10天,因为他的回调函数市detail_page,所以共享detail_page的config
Handler.crawl_config = {}
全局参数
class Handler(BaseHandler):
crawl_config = {
'headers': {
'User-Agent': 'GoogleBot',
}
}
...
二 response
Response.url
Response.text
Content of response, in unicode.if Response.encoding is None and chardet module is available, encoding of content will be guessed.
Response.content
Response.doc
pyspider封装的一个 PyQuery对象看
Response.etree
lxml对象
Response.json
json对象
Response.status_code
Response.orig_url
如果在请求期间有任何重定向,这里是您通过self.crawl提交的URL。
Response.headers
不区分大小写的dict保存响应的头。
Response.cookies
Response.error
http请求的错误信息
Response.cookies
Response.time
http请求时间
Response.ok
如果请求成功为Ture
Response.encoding
response.content的编码。如果response.encoding为none,编码将由header、content或chardet(如果可用)进行猜测。手动设置内容编码将覆盖猜测的编码。
Response.save
self.crawl api保存的对象
Response.js_script_result
JS脚本返回的内容
Response.raise_for_status()
如果状态代码不是200或response.error存在,则引发httperror。
三 self.send_message
self.send_message(project, msg, [url])
向其他项目发送消息。可以通过def on_message(self,project,message)
回调接收。
-
project
发送消息的项目名称 -
msg
json对象 -
url
result will been overwrite if have same taskid. send_message share a same taskid by default. Change this to return multiple result by one response
pyspider send_message [OPTIONS] PROJECT MESSAGE
你也可以通过命令行发送消息给其它项目
Usage: pyspider send_message [OPTIONS] PROJECT MESSAGE
Send Message to project from command line
Options:
--scheduler-rpc TEXT xmlrpc path of scheduler
--help Show this message and exit.
def on_message(self, project, message)
从其它项目接收消息
四 @catch_status_code_error
非200响应将被视为获取失败,不会传递到回调。使用此修饰符覆盖此功能。
def on_start(self):
self.crawl('http://httpbin.org/status/404', self.callback)
@catch_status_code_error
def callback(self, response):
...
五 @every(minutes=0, seconds=0)
该方法将每隔几分钟或几秒调用一次
@every(minutes=24 * 60)
def on_start(self):
for url in urllist:
pass
URL将每24小时重新启动一次。请注意,如果还使用了age,并且该时间段比@every长,则将放弃爬网请求,因为它被视为未更改:
@every(minutes=24 * 60)
def on_start(self):
self.crawl('http://www.example.org/', callback=self.index_page)
@config(age=10 * 24 * 60 * 60)
def index_page(self):
...
尽管爬行请求每天都会触发,但它被丢弃,并且只每隔10天重新启动一次。