Python3 PySpider爬虫框架-使用

  • pyspider的架构主要分为Scheduler调度器Fetcher抓取器Processer处理器三部分,整个抓取过程都会受到Monitor监控器的监控,抓取的结果被Result Worker结果处理器处理
  • 点击Create按钮创建新项目
 1 #!/usr/bin/env python
 2 # -*- encoding: utf-8 -*-
 3 # Created on 2019-07-10 15:17:59
 4 # Project: baidu_spider
 5 from pyspider.libs.base_handler import *
 6 # BaseHandler是PySpider爬虫的基类
 7 class Handler(BaseHandler):
 8     """Handler是PySpider爬虫的主类"""
 9     crawl_config = {
10         # 定义爬取配置,比如Headers、设置代理,配置之后全局有效
11     }
12     @every(minutes=24 * 60) # every属性设置爬取的时间间隔
13     def on_start(self):
14         """爬取入口,调用crawl方法新建一个爬取请求,第一个参数是爬取的URL,callback参数是指定这个页面爬取成功之后使用哪个方法解析"""
15         self.crawl('https://www.liaoxuefeng.com/', callback=self.index_page)
16         """http://travel.qunar.com/travelbook/list.htm"""
17     @config(age=10 * 24 * 60 * 60)
18     def index_page(self, response):
19         """接收response参数,该参数对接pyquery,可以直接使用doc进行解析"""
20         for each in response.doc('a[href^="http"]').items():
21             self.crawl(each.attr.href, callback=self.detail_page)
22     @config(priority=2)
23     def detail_page(self, response):
24         """接收response参数,进行详情页的抓取"""
25         return {
26             "url": response.url,
27             "title": response.doc('title').text(),
28         }
  • 点击run按钮,即可看见页面下方follow出现一个标注,其中包含数字1,代码有新的爬取请求产生
  • 点击蓝色框围起来的箭头,在follows上会出现更多的爬取请求(爬取链接);其中web按钮可以查看页面,html按钮可以查看源代码
  • 切换到Web页面,点击下方的enable css selector helper按钮,点击页面中的菜单,这时菜单外会多一个红框,上分出现CSS选择器,这就是当前菜单对应的CSS选择器,可以替换右侧代码中的CSS选择器(选择需要替换的CSS选择器),点击右上方的箭头实现替换
  • 在源代码中没有img节点:这是因为pyspider是默认发生HTTP请求,请求的HTML文档本身就不包含img节点,所以必须修改fetch_type参数
self.crawl(url, callback=self.index_page, validate_cert=False, fetch_type='js')
  • index_page方法选取爬取的详情页链接,通过编写detail_page需要爬取的信息
  • 将爬虫的status设置为DEBUG或者RUNNING,点击Run按钮开始爬取
  • 点击Active Tasks,即可查看最近请求的详细状况
  • 点击Result,即可查看所有的爬取结果
  • 项目状态
    • TODO:他是项目刚刚被创建还未实现时的状态
    • STOP:如果想停止某项目的爬取,可以将项目的状态设置为STOP
    • CHECKING:正在运行的项目被修改之后会变成该状态,项目在中途出错需要调整的时候回遇见这种情况
    • DEBUG/RUNNING:这两个状态对项目运行没有影响,设置为其中一个,项目都可以运行,但是可以用二者来区分项目是否已经通过测试
    • PAUSE:在爬取过程中会出现连续多次错误,项目会自动设置为PAUSE状态,并等待一段时间继续爬取
  • rate/burst:代表当前爬取的速率,rate代码1秒发出多少请求,burst相当于流量控制中的令牌桶算法的令牌数,rate和burst设置越大,爬取速率越快,需要考虑本机性能和爬取过快被封的问题
  • progress:中的5m1h1d指定是最近5分钟、1小时、1天内的请求情况,all代表全部请求情况,其中蓝色代表等待被执行的请求,绿色代表成功的请求,黄色代表请求识别后等待重试的请求,红色代表失败次数过多而被忽略的请求
  • 删除项目:pyspider没有直接删除项目的选项,如果需要删除项目,只能将项目的状态设置为STOP,将分组的名称设置为delete,等待24小时,则项目会自动删除
  • 报错Exception: HTTP 599: SSL certificate problem: unable to get local issuer certificate
    • 解决方法:这个错误会发生在请求 https 开头的网址,SSL 验证错误,证书有误,需要在crawl方法中使用validate_cert参数,基本可以解决
1 self.crawl(url, callback=self.index_page, validate_cert=False)
    • 上述方法解决不了的情况下:第一步在Github上下载Pyspider源码,源码地址https://github.com/binux/pyspider;第二步下载之后的源码,找到其中的pyspider文件夹,替换本地的pyspider库安装文件夹,pip安装一般存放在" ..Lib\site-packages"路径下;第三步重启Pyspider,添加validate_cert=False参数
  • self.crawl函数分析
self.crawl(url, callback=self.index_page, age=10*24*60*60, priority=1, exectime=time.time()+30*60, itag=item.find('.time').text(), auto_recrawl=True)
# url:要爬取的URL
# callback:回调函数,指定该url对应的响应内容用哪个方法解析
# age:是任务的有效时间,如果某个任务在有效时间内已经被执行,则它不会重复执行,单位秒,或者直接在回调函数上设置修饰器@config(age=10*24*60*60)
# priority:爬取任务优先级,默认为0,该参数值越大,对应的请求会越优先被调用
# exectime:可以设置定时任务,其值是时间戳,默认为0,即代表立即执行
# retries:定义重试次数,默认为3
# itag:设置判断页面是否发生变化的节点值,在爬取的时候回判定次当前节点是否和上次爬取的节点相同,如果节点相同,则证明页面没有更新
# auto_recrawl:设置为True;age为5小时,这样任务会每5小时执行一次
# method:HTTP请求方法,默认为GET
# params:GET请求参数,字典类型
# data:post表单数据,字典类型
# file:上传的文件,需要指定文件名,{field: {filename: 'content'}}
# user-agent:爬取使用的User-Agent
# headers:爬取使用的Request Header
# cookies:爬取时使用的Cookies,字典格式
# connect_timeout:初始化连接是的最长等待时间,默认20秒
# timeout:爬取网页时最长的等待时间,默认120秒
# allow_redirects:是否自动处理重定向,默认为True
# validate_cert:是否验证证书,对HTTPS请求有用
# proxy:爬取时的代理,它支持username:password@hostname:port;
# fetch_type:开启PhantomJS渲染,如果遇见JavaScript渲染的页面,指定该字段即实现PhantomJS的对接
self.crawl('http://www.example.org/', callback=self.callback, fetch_type='js', js_script='''function() { window.scrollTo(0,document.body.scrollHeight);return 123;} ''')
# js_script:是页面加载完毕后执行的JavaScript脚本
# js_run_at:JavaScript脚本运行的位置,是在页面节点开头还是结尾,m默认结尾,即document-end
# js_viewport_width/js_viewport_height:JavaScript渲染页面时的窗口大写
# load_images:加载JavaScript页面时确定是否加载图片,默认False
def on_start(self):
    self.crawl('http://www.example.org/', callback=self.callback,save={'a': 123})
def callback(self, response):
    return response.save['a']
# save:用于在不同方法之间传递参数
# cancel:是取消任务,如果一个任务是ACTIVE状态的,需要将force_update=True
# force_update:即使任务处于ACTIVE,那也会强制性更新状态
  • 任务区分:在pyspider判断两个任务是否是重复的是使用该任务对于的URL的MD5值作为任务唯一的ID,如果ID相同,那么那个任务就会判相同,其中一个就不会爬取,但是很多情况下请求链接可能是同一个,但是POST的参数不同,这时就可以重写task_is()方法,改变ID的计算方法
1 import json
2 from pyspider.libs.utils import md5string
3 def get_taskid(self, task):
4     return md5string(task['url']+json.dumps(task['fecth'].get('data','')))

 

 
posted @ 2020-08-23 22:08  陨落的星尘  阅读(268)  评论(0编辑  收藏  举报