scrapy基础通盘总结
Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,我们只需要实现少量的代码,就能够快速的抓取
Scrapy使用了Twisted异步网络框架,可以加快我们的下载速度
工作图片流程解释 :
1 spiders 从setting中获取配置 从Scheduler中获取网址 交给调度器调度器判断之后 交给下载 中间件----》网页数据
2 网页数据返回 -------》下载中间件--------------》调度器 -----------》调度器把数据给管道文件Pip
-------------》可以从数据中获取另外的url然后重复第一步存在
创建命令scrapy项目命令:scrapy startproject name
创建爬虫 —》先进入到spider文件夹中--------》 scrapy genspider name name.com
首先来讲讲各个py文件
1:spider爬虫文件
下面这些就是基础用到的一些东西和一个回调
import scrapy
class Demo1Spider(scrapy.Spider):
name = 'demo1' # 爬虫名字
allowed_domains = ['careers.tencent.com'] # 限制爬虫的爬取的域名
start_urls = ['https://careers.tencent.com/login'] # 第一次爬取的网页地址
"""
def start_requests(self):
# 这个方法可以重写
# 在获取数据之前可以为请求添加设置 比如cookie模拟登录
# 也可以回调到parse
pass
"""
def parse(self, response):
"""
爬取网页后返回的数据
:param response:
:return:
"""
"""
yield scrapy.Request(self, url=None, callback=None, method='GET', headers=None, body=None,
cookies=None, meta=None, encoding='utf-8', priority=0,
dont_filter=False, errback=None, flags=None, cb_kwargs=None)
# url是要爬取的网址
# callback是回调函数
# method是请求的方式post还是get
# headers是浏览器伪装的头信息
# body是网页源代码信息
# cookies是登入某网站后,网站在你电脑上保留的信息
# meta要携带或者传递的信息
# encoding是编码方式
# priority用来设置访问网站的优先级
# dont_filter是否允许重复爬取网站
"""
pass
2 items.py文件
# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
# items存在的意义就是规范保存数据的键
import scrapy
class Myspider2Item(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
# name就是一个键 如果存储了别的名字就会报错
pass
3 Pipeline.py文件
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
import json
"""
要想使用这个文件必须打开
ITEM_PIPELINES
setting 中打开
从pipeline的字典形可以看出来,pipeline可以有多个,而且确实pipeline能够定义多个
为什么需要多个pipeline:
1 可能会有多个spider,不同的pipeline处理不同的item的内容
2 一个spider的内容可以要做不同的操作,比如存入不同的数据库中
注意:
1 pipeline的权重越小优先级越高
2 pipeline中process_item方法名不能修改为其他的名称
"""
class PoetryZfPipeline:
"""
处理数据的文件
下面的函数是重写 不能随意更改名字
"""
def __init__(self):
"""
可以做一次额初始化的存在
比如文件的打开
"""
self.f = open('poetry.json', 'w', encoding='utf-8')
def open_spider(self, item):
"""
爬虫开始的函数 可以提示也可以做一些其他的操作
:param item:
:return:
"""
print('爬虫开始了')
def process_item(self, item, spider):
"""
item 就是从spider中返回过来的数据
spider就是返回过来的爬虫 比如 spider.name就是爬虫的名字
对数据进行处理的文件
:param item:
:param spider:
:return:
"""
self.f.write(json.dumps(dict(item), ensure_ascii=False) + '\n')
return item
def close_spider(self, item):
"""
爬虫关闭时执行的函数
:param item:
:return:
"""
print('爬虫结束了')
self.f.close()
4 setting.py文件
为什么需要配置文件:
配置文件存放一些公共的变量(比如数据库的地址,账号密码等)
方便自己和别人修改
一般用全大写字母命名变量名 SQL_HOST = ‘192.168.0.1’
BOT_NAME
默认: 'scrapybot'
Scrapy项目实现的bot的名字。用来构造默认 User-Agent,同时也用来log。
当你使用 startproject 命令创建项目时其也被自动赋值。
CONCURRENT_ITEMS
默认: 100
Item Processor(即 Item Pipeline) 同时处理(每个response的)item的最大值
CONCURRENT_REQUESTS
默认: 16
Scrapy downloader 并发请求(concurrent requests)的最大值。
CONCURRENT_REQUESTS_PER_DOMAIN
默认: 8
对单个网站进行并发请求的最大值。
CONCURRENT_REQUESTS_PER_IP
默认: 0
对单个IP进行并发请求的最大值。如果非0,则忽略 CONCURRENT_REQUESTS_PER_DOMAIN 设定, 使用该设定。 也就是说,并发限制将针对IP,而不是网站。
该设定也影响 DOWNLOAD_DELAY: 如果 CONCURRENT_REQUESTS_PER_IP 非0,下载延迟应用在IP而不是网站上。
DEFAULT_ITEM_CLASS
默认: 'scrapy.item.Item'
the Scrapy shell 中实例化item使用的默认类。
DEFAULT_REQUEST_HEADERS
默认:
{
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
}
Scrapy HTTP Request使用的默认header。由 DefaultHeadersMiddleware 产生。
DOWNLOADER
默认: 'scrapy.core.downloader.Downloader'
用于crawl的downloader.
DOWNLOADER_MIDDLEWARES
默认:: {}
保存项目中启用的下载中间件及其顺序的字典。
DOWNLOAD_DELAY
默认: 0
下载器在下载同一个网站下一个页面前需要等待的时间。该选项可以用来限制爬取速度, 减轻服务器压力。同时也支持小数:
DOWNLOAD_HANDLERS
默认: {}
保存项目中启用的下载处理器(request downloader handler)的字典。
DOWNLOAD_TIMEOUT
默认: 180
下载器超时时间(单位: 秒)。
EXTENSIONS
默认:{}
保存项目中启用的插件及其顺序的字典。
ITEM_PIPELINES
默认: {}
保存项目中启用的pipeline及其顺序的字典。该字典默认为空,值(value)任意。 不过值(value)习惯设定在0-1000范围内。
ITEM_PIPELINES_BASE
默认: {}
保存项目中默认启用的pipeline的字典。 永远不要在项目中修改该设定,而是修改 ITEM_PIPELINES 。
LOG_ENABLED
默认: True
是否启用logging。
LOG_ENCODING
默认: 'utf-8'
logging使用的编码。
LOG_FILE
默认: None
logging输出的文件名。如果为None,则使用标准错误输出(standard error)。
LOG_FORMAT
默认: '%(asctime)s [%(name)s] %(levelname)s: %(message)s'
日志的数据格式
LOG_DATEFORMAT
默认: '%Y-%m-%d %H:%M:%S'
日志的日期格式
LOG_LEVEL
默认: 'DEBUG'
log的最低级别。可选的级别有: CRITICAL、 ERROR、WARNING、INFO、DEBUG。
LOG_STDOUT
默认: False
如果为 True ,进程所有的标准输出(及错误)将会被重定向到log中。
RANDOMIZE_DOWNLOAD_DELAY
默认: True
如果启用,当从相同的网站获取数据时,Scrapy将会等待一个随机的值 (0.5到1.5之间的一个随机值 * DOWNLOAD_DELAY)。
该随机值降低了crawler被检测到(接着被block)的机会。某些网站会分析请求, 查找请求之间时间的相似性。
REDIRECT_MAX_TIMES
默认: 20
定义request允许重定向的最大次数。超过该限制后该request直接返回获取到的结果。 对某些任务我们使用Firefox默认值。
ROBOTSTXT_OBEY
默认: False
是否遵循robots协议
SCHEDULER
默认: 'scrapy.core.scheduler.Scheduler'
用于爬取的调度器。
SPIDER_MIDDLEWARES
默认: {}
保存项目中启用的下载中间件及其顺序的字典。
USER_AGENT
默认: "Scrapy/VERSION (+http://scrapy.org)"
爬取的默认User-Agent,除非被覆盖。
Scrapy 下载中间件
Download Middlewares
在爬虫中间件中 可以设置代理ip 和 请求头
下载中间件是scrapy提供用于用于在爬虫过程中可修改Request和Response,用于扩展scrapy的功能
使用方法:
• 编写一个Download Middlewares和我们编写一个pipeline一样,定义一个类,然后再settings中开启
Download Middlewares默认方法:
处理请求,处理响应,对应两个方法
process_request(self,request,spider):
当每个request通过下载中间件时,该方法被调用
process_response(self,request,response,spider):
当下载器完成http请求,传递响应给引擎的时候调用
process_request(request,spider)
当每个Request对象经过下载中间件时会被调用,优先级越高的中间件,越先调用;该方法应该返回以下对象:None/Response对象/Request对象/抛出IgnoreRequest异常
• 返回None:scrapy会继续执行其他中间件相应的方法;
• 返回Response对象:scrapy不会再调用其他中间件的process_request方法,也不会去发起下载,而是直接返回该Response对象
• 返回Request对象:scrapy不会再调用其他中间件的process_request()方法,而是将其放置调度器待调度下载
• 如果这个方法抛出异常,则会调用process_exception方法
process_response(request,response,spider)
当每个Response经过下载中间件会被调用,优先级越高的中间件,越晚被调用,与process_request()相反;该方法返回以下对象:Response对象/Request对象/抛出IgnoreRequest异常。
• 返回Response对象:scrapy会继续调用其他中间件的process_response方法;
• 返回Request对象:停止中间器调用,将其放置到调度器待调度下载;
• 抛出IgnoreRequest异常:Request.errback会被调用来处理函数,如果没有处理,它将会被忽略且不会写进日志。
- 设置随机请求头
爬虫在频繁访问一个页面的时候,这个请求如果一直保持一致。那么很容易被服务器发现,从而禁止掉这个请求头的访问。因此我们要在访问这个页面之前随机的更改请求头,这样才可以避免爬虫被抓。随机更改请求头,可以在下载中间件实现。在请求发送给服务器之前,随机的选择一个请求头。这样就可以避免总使用一个请求头
测试请求头网址: http://httpbin.org/user-agent
在middlewares.py文件中
class RandomUserAgent(object):
def process_request(self, request, spider):
"""
中间件中的函数
从setting文件中获取 我们定义好的 代理ip 和 请求头随机获取一个
:param self:
:param request:
:param spider:
:return:
"""
proxy = random.choice(settings['PROXIES'])
request.meta['proxy'] = proxy
user_agent = random.choice(spider.settings['USER_AGENTS'])
request.headers['User-Agent'] = user_agent
def process_response(self,request,response,spider):
"""
打印请求头
"""
print(request.headers['User-Agent'])
return response
请求头网址:http://www.useragentstring.com/pages/useragentstring.php?typ=Browser
常用ua
http://www.useragentstring.com/pages/useragentstring.php?typ=Browser
USER_AGENTS= [
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36",
"Dalvik/1.6.0 (Linux; U; Android 4.2.1; 2013022 MIUI/JHACNBL30.0)",
"Mozilla/5.0 (Linux; U; Android 4.4.2; zh-cn; HUAWEI MT7-TL00 Build/HuaweiMT7-TL00) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
"AndroidDownloadManager",
"Apache-HttpClient/UNAVAILABLE (java 1.4)",
"Dalvik/1.6.0 (Linux; U; Android 4.3; SM-N7508V Build/JLS36C)",
"Android50-AndroidPhone-8000-76-0-Statistics-wifi",
"Dalvik/1.6.0 (Linux; U; Android 4.4.4; MI 3 MIUI/V7.2.1.0.KXCCNDA)",
"Dalvik/1.6.0 (Linux; U; Android 4.4.2; Lenovo A3800-d Build/LenovoA3800-d)",
"Lite 1.0 ( http://litesuits.com )",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727)",
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 SE 2.X MetaSr 1.0",
"Mozilla/5.0 (Linux; U; Android 4.1.1; zh-cn; HTC T528t Build/JRO03H) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30; 360browser(securitypay,securityinstalled); 360(android,uppayplugin); 360 Aphone Browser (2.0.4)",
]