Scrapy框架
【一】介绍
1)开源和协作的框架
-
其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,
-
使用它可以以快速、简单、可扩展的方式从网站中提取所需的数据。
-
但目前Scrapy的用途十分广泛,可用于如数据挖掘、监测和自动化测试等领域,也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫。
-
Scrapy 是基于twisted框架开发而来,twisted是一个流行的事件驱动的python网络框架。
-
因此Scrapy使用了一种非阻塞(又名异步)的代码来实现并发。
-
Scrapy框架类似于Django框架
2)安装
pip install scrapy
【二】基本使用
1)全局命令和项目命令
# 全局命令
Global commands:
startproject #创建项目
genspider #创建爬虫程序
settings #如果是在项目目录下,则得到的是该项目的配置
runspider #运行一个独立的python文件,不必创建项目
shell #scrapy shell url地址 在交互式调试,如选择器规则正确与否
fetch #独立于程单纯地爬取一个页面,可以拿到请求头
view #下载完毕后直接弹出浏览器,以此可以分辨出哪些数据是ajax请求
version #scrapy version 查看scrapy的版本,scrapy version -v查看scrapy依赖库的版本
# 项目命令
Project-only commands:
crawl #运行爬虫,必须创建项目才行,确保配置文件中ROBOTSTXT_OBEY = False
check #检测项目中有无语法错误
list #列出项目中所包含的爬虫名
parse #scrapy parse url地址 --callback 回调函数 #以此可以验证我们的回调函数是否正确
bench #scrapy bentch压力测试
2)创建项目
# 创建项目命令
scrapy startproject 项目名
# scrapy startproject SpiderNewsProjects
# 进入爬虫项目文件
cd SpiderNewsProjects
# 创建spider项目(自定义的爬虫程序脚本)
scrapy genspider 自定爬虫程序文件名 目标网址
├── NewsPro # 项目名
│ ├── __init__.py
│ ├── items.py # 类似于django的 models表模型,一个个模型类
│ ├── middlewares.py # 中间件
│ ├── pipelines.py # 管道---》写持久化
│ ├── settings.py # 项目配置文件
│ └── spiders # 里面放了自定义的爬虫,类似于app
│ ├── __init__.py
│ ├── huanqiu.py # 自定义爬虫文件
│ └── wangyi.py # 自定义爬虫文件
└── scrapy.cfg # 项目上线配置
3)启动项目
# 在最外层的项目名目录终端使用
scrapy crawl wangyi
# 创建一个start.py文件
from scrapy.cmdline import execute
# 默认打开日志
execute(['scrapy', 'crawl', '自定义爬虫文件名'])
# 关闭日志
execute(['scrapy', 'crawl', '自定义爬虫文件名', "--nolog"])
4)启动优化
1.降低日期等级
- settings.py中添加指定配置项
# 指定输出日志的类型:
LOG_LEVEL = 'ERROR'
2.不遵循ROBOTS协议
ROBOTSTXT_OBEY = False
3.以启动文件启动项目
- 创建一个start.py文件
from scrapy.cmdline import execute
execute(['scrapy', 'crawl', '自定义爬虫文件名', "--nolog"])
【三】数据解析
1)项目准备
- 创建
# 创建项目
scrapy startproject 项目名称
# 切换到项目目录
cd 项目名称
# 3.创建爬虫文件
scrapy genspider 爬虫文件名 www.xxx.com
# 4.配置文件修改(settings.py)
ROBOTSTXT_OBEY = False # 不遵从robots协议
LOG_LEVEL = 'ERROR' # 指定输出日志的类型:
from fake_useragent import UserAgent
USER_AGENT = UserAgent().random # 指定UA
# 5.编写爬虫文件(spiders/爬虫文件名.py
- 启动
# 命令启动
scrapy crawl spider_news
# 新建启动文件
from scrapy.cmdline import execute
execute(['scrapy', 'crawl', '爬虫文件名', "--nolog"])
2)爬虫文件结构分析
import scrapy
# 爬虫类,继承了scrapy.Spider
class FirstSpider(scrapy.Spider):
# 爬虫文件的名称,是当前爬虫文件的唯一标识
name = "first"
# 允许访问的域名
allowed_domains = ["www.cnblogs.com/"]
# 起始的url列表:可以将即将被请求的url,存放在当前列表中。
# 默认情况,列表中存储的url都会被scrapy框架进行get请求的发送
start_urls = ["https://www.cnblogs.com/"]
# 实现数据解析
# 参数response表示请求对应的响应对象
# parse方法调用的次数取决于请求的次数
def parse(self, response):
# 可以在响应对象中直接使用xpath进行数据解析
pass
3)css解释器
response.css(‘a’)
# 返回的是selector对象,
response.css(‘a’).extract()
# 返回的是a标签对象
response.css(‘a::text’).extract_first()
# 返回的是第一个a标签中文本的值
response.css(‘a::attr(href)’).extract_first()
# 返回的是第一个a标签中href属性的值
response.css(‘a[href*=image]::attr(href)’).extract()
# 返回所有a标签中href属性包含image的值
response.css(‘a[href*=image] img::attr(src)’).extract()
# 返回所有a标签下image标签的src属性
4)Xpath解析器
1.路径表达式
表达式 | 描述 | 实例 |
---|---|---|
nodename | 选取nodename节点的所有子节点 | //div |
/ | 从根节点选取 | /div |
// | 选取任意位置的节点,不考虑他们的位置 | //div |
. | 选取当前节点 | ./div |
.. | 选取当前节点的父节点 | .. |
@ | 选取属性 | //@class |
2.通配符
表达式 | 结果 |
---|---|
//* | 选取所有元素 |
//div/* | 选取所有属于div元素的所有子节点 |
//div[@*] | 选取所有带属性的元素 |
3.获取多个路径
表达式 | 结果 |
---|---|
//div | //table | 选取文档中所有的div和table节点 |
//div/a | //div/p | 选取所有div元素的a和p 元素 |
//div/pl | //span | 选取所有div下的pl和文档中所有span |
5)获取数据
1.extract_first()
- 在Scrapy选择器返回的SelectorList对象上调用此方法时,将提取匹配该选择器的第一个HTML/XML元素的内容。
- 如果找到匹配项,则返回该元素的字符串形式;否则返回None。
response.css('div.title').extract_first()
2.extract()
- 当调用此方法时,它将提取所有匹配该选择器的HTML/XML元素的内容,返回一个包含所有匹配元素字符串形式的列表。
all_titles = response.css('div.title').extract()
【四】配置文件
1)基础配置
#1.项目名字,整个爬虫名字
BOT_NAME = "firstscrapy"
#2.爬虫存放位置的设置
SPIDER_MODULES = ["firstscrapy.spiders"]
NEWSPIDER_MODULE = "firstscrapy.spiders"
#3.是否遵循爬虫协议,一般都设为False
ROBOTSTXT_OBEY = False
#4.User-Agent设置
USER_AGENT = "firstscrapy (+http://www.yourdomain.com)"
#5.日志级别设置
LOG_LEVEL='ERROR'
#6.DEFAULT_REQUEST_HEADERS 默认请求头
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
}
#7.SPIDER_MIDDLEWARES 爬虫中间件
SPIDER_MIDDLEWARES = {
'cnblogs.middlewares.CnblogsSpiderMiddleware': 543,
}
#8.DOWNLOADER_MIDDLEWARES 下载中间件
DOWNLOADER_MIDDLEWARES = {
'cnblogs.middlewares.CnblogsDownloaderMiddleware': 543,
}
#9.ITEM_PIPELINES 持久化配置
ITEM_PIPELINES = {
'cnblogs.pipelines.CnblogsPipeline': 300,
}
2)高级配置
#1.增加并发数,默认为16,可以根据需求进行调整
# 默认scrapy开启的并发线程为32个,可以适当进行增加。
# 值为100,并发设置成了为100。
# 在settings配置文件中修改
CONCURRENT_REQUESTS = 100
#2.降低日志级别,可设置为INFO或ERROR,减少日志输出,提高性能
# 在运行scrapy时,会有大量日志信息的输出,为了减少CPU的使用率。
# 可以设置log输出信息为INFO或者ERROR即可。
在配置文件中编写:
LOG_LEVEL = 'INFO'
#3.禁止使用Cookie,默认为True,如果不需要使用Cookie可以设置为False
# 如果不是真的需要cookie,则在scrapy爬取数据时可以禁止cookie从而减少CPU的使用率,提升爬取效率。
COOKIES_ENABLED = False
#4.禁止重试,默认为True,如果不需要进行重试请求可以设置为False
# 对失败的HTTP进行重新请求(重试)会减慢爬取速度,因此可以禁止重试。
RETRY_ENABLED = False
#5.设置下载超时时间,默认180秒,可以根据需求进行调整
# 如果对一个非常慢的链接进行爬取,减少下载超时可以能让卡住的链接快速被放弃,从而提升效率。
# 超时时间为10s
DOWNLOAD_TIMEOUT = 10
【五】持久化存储
1)pipline存储(管道)
-
process_item(self,item,spoder)
- 管道类中必须的函数,实现对item数据的处理
-
open_spider(self,spider)
- 在爬虫开启时执行一次
-
close_spider(self,spider)
- 在爬虫关闭的时候执行一次
2)博客园案例
1.创建管道数据模型
- 在item.py中写一个类
import scrapy
class BlogItem(scrapy.Item):
# 创建管道字典:类似于Django中的模型表
# 当前文章的文章标题
article_title = scrapy.Field()
# 当前文章的详情链接
article_link = scrapy.Field()
# 当前文章的简介
article_desc = scrapy.Field()
# 当前文章作者的头像链接
article_author_avatar_url = scrapy.Field()
# 当前文章的作者名字
article_author_name = scrapy.Field()
# 当前作者的详情链接
article_author_url = scrapy.Field()
# 当前文章的发布日期
article_publish_date = scrapy.Field()
# 当前文章的点赞数
article_up_num = scrapy.Field()
# 当前文章的评论数
article_comment_num = scrapy.Field()
# 当前文章的阅读数
article_read_num = scrapy.Field()
2.定义管道数据处理类
-
pipline.py中创建一个类
-
open_spide:开启爬虫会触发
close_spider:爬完会触发
process_item:每次要保存一个对象会触发
-
# 数据库建表
CREATE DATABASE IF NOT EXISTS cnblogs DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
DROP TABLE IF EXISTS cnblogs;
CREATE TABLE article(
`id` INT NOT NULL AUTO_INCREMENT COMMENT '主键;主键ID' ,
`title` VARCHAR(255) COMMENT '文章标题;文章标题' ,
`link` VARCHAR(255) COMMENT '文章详情地址' ,
`desc` VARCHAR(255) COMMENT '文章简介' ,
`content` TEXT COMMENT '文章内容' ,
`author_avatar_url` VARCHAR(255) COMMENT '文章作者头像URL地址' ,
`author_name` VARCHAR(255) COMMENT '文章作者名字' ,
`author_url` VARCHAR(255) COMMENT '文章作者链接' ,
`publish_date` VARCHAR(255) COMMENT '文章发布日期' ,
`up_num` VARCHAR(255) COMMENT '文章点赞数' ,
`comment_num` VARCHAR(255) COMMENT '文章评论数' ,
`read_num` VARCHAR(255) COMMENT '文章阅读数' ,
PRIMARY KEY (id)
) COMMENT = '';
# 配置文件
import pymysql
class BlogCloudFilePipeline:
# 启动爬虫项目会触发
def open_spider(self, spider):
# 定义起始调用次数
self.count = 0
# 创建mysql链接对象
self.conn = pymysql.connect(
user="root",
password="1314521",
host="127.0.0.1",
port=3306,
database='cnblogs'
)
# 创建句柄
self.cursor = self.conn.cursor()
# 关闭爬虫项目会触发
def close_spider(self, spider):
# 关闭句柄
self.cursor.close()
# 关闭mysql数据库链接
self.conn.close()
# 这个很重要
# 管道中转站,所有管道数据都必须经过的方法
def process_item(self, item, spider):
# 调用次数 +1
self.count += 1
# 打印调用次数
print(self.count)
# 定义插入数据的SQL语句
sql = "INSERT INTO article(title, link) VALUES ( %s, %s)"
self.cursor.execute(
sql,
args=(
item.get('article_title'),
item.get('article_link')
)
)
# 每次存储数据都提交数据,防止数据丢失
self.conn.commit()
# 必须将 item 对象返回,下次调用
return item
3.配置文件注册管道类
- settings.py
# 管道类
ITEM_PIPELINES = {
# 项目自带的默认管道类
# "SpiderFirst.pipelines.SpiderfirstPipeline": 300,
# 注册自己写的管道类 : 保存数据到本地,数字越小,优先级越高,依次执行
"SpiderFirst.pipelines.BlogLocalFilePipeline": 300,
# 注册自己写的管道类 : 保存数据到数据库,数字越小,优先级越高,依次执行
"SpiderFirst.pipelines.BlogCloudFilePipeline": 301,
}
4.处理数据
- parse/yield/item
import scrapy
# 从 items.py 中导入创建好的管道类模型表
from ..items import BlogItem
# 自动创建以当前文件名为名的爬虫类
class CnblogSpider(scrapy.Spider):
# 爬虫程序的唯一标识
name = "cnblog"
# 允许访问的域名
allowed_domains = ["www.123.com"]
# 起始 URL
start_urls = ["https://www.cnblogs.com/"]
# 解析函数
def parse(self, response):
# 构建数据列表,存储文章数据
article_data_list = []
# 创建 管道 对象 (item对象)
item = BlogItem()
# 获取所有的文章对象
article_section_list = response.xpath('//*[@id="post_list"]/article/section')
# 遍历获取每一篇文章的数据
for article_section in article_section_list:
# 获取当前文章信息
article_info = article_section.xpath('./div')
# 获取当前文章的文章标题
article_title = article_info.xpath('./a/text()').extract_first()
# 获取当前文章的详情链接
article_link = article_info.xpath('./a/@href').extract_first()
# 获取当前文章的简介
try:
article_desc = article_info.xpath('./p/text()').extract()[1].strip()
except:
article_desc = ""
# 获取当前文章作者的头像链接
article_author_avatar_url = article_info.xpath('./p/a/img/@src').extract_first()
# 获取当前作者信息
article_author_info = article_section.xpath('./footer')
# 获取当前文章的作者名字
article_author_name = article_author_info.xpath('./a[1]/span/text()').extract_first()
# 获取当前作者的详情链接
article_author_url = article_author_info.xpath('./a[1]/@href').extract_first()
# 获取当前文章的发布日期
article_publish_date = article_author_info.xpath('./span[1]/span/text()').extract_first()
# 获取当前文章的点赞数
article_up_num = article_author_info.xpath('./a[2]/span/text()').extract_first()
# 获取当前文章的评论数
article_comment_num = article_author_info.xpath('./a[3]/span/text()').extract_first()
# 获取当前文章的阅读数
article_read_num = article_author_info.xpath('./a[4]/span/text()').extract_first()
# 构造当前文章的字典信息
data = {
"article_title": article_title,
"article_link": article_link,
"article_desc": article_desc,
"article_author_name": article_author_name,
"article_author_avatar_url": article_author_avatar_url,
"article_author_url": article_author_url,
"article_publish_date": article_publish_date,
"article_up_num": article_up_num,
"article_comment_num": article_comment_num,
"article_read_num": article_read_num,
"article_content": ""
}
# 向管道中提交数据 : 注意这里是抓到一条提交一条,也可以全部抓取后批量处理
item.update(data)
# 不要忘了提价管道,否则管道数据不生效!
yield item
# 全部抓取后更新数据
item.update(*article_data_list)
yield item
# 将当前文章的字典信息添加到列表中
article_data_list.append(data)
return article_data_list
5.启动项目
scrapy crawl cnblog
【六】全站爬取
1)Request创建
yield Request(url=url, callback=self.detail_parse,meta={'item':item})
2)Response对象
def parser_detail(self,response):
# 获取到传入的 item 对象
item=response.meta.get('item')
# 继续解析需要解析的内容
content=str(response.xpath('//div[@id="cnblogs_post_body"]').extract_first())
# 向 item 对象中添加信息
item['content']=content
# 将完整的信息 返回
yield item
3)示例
import scrapy
from scrapy import Request
# 从 items.py 中导入创建好的管道类模型表
from ..items import BlogItem
# 自动创建以当前文件名为名的爬虫类
class CnblogSpider(scrapy.Spider):
# 爬虫程序的唯一标识
name = "cnblog"
# 允许访问的域名
allowed_domains = ["www.cnblogs.com"]
# 起始 URL
start_urls = ["https://www.cnblogs.com/"]
# 解析函数
def parse(self, response):
# 构建数据列表,存储文章数据
article_data_list = []
# 创建 管道 对象 (item对象)
item = BlogItem()
# 获取所有的文章对象
article_section_list = response.xpath('//*[@id="post_list"]/article/section')
# 遍历获取每一篇文章的数据
for article_section in article_section_list:
# 获取当前文章信息
article_info = article_section.xpath('./div')
# 获取当前文章的文章标题
article_title = article_info.xpath('./a/text()').extract_first()
# 获取当前文章的详情链接
article_link = article_info.xpath('./a/@href').extract_first()
# 获取当前文章的简介
try:
article_desc = article_info.xpath('./p/text()').extract()[1].strip()
except:
article_desc = ""
# 获取当前文章作者的头像链接
article_author_avatar_url = article_info.xpath('./p/a/img/@src').extract_first()
# 获取当前作者信息
article_author_info = article_section.xpath('./footer')
# 获取当前文章的作者名字
article_author_name = article_author_info.xpath('./a[1]/span/text()').extract_first()
# 获取当前作者的详情链接
article_author_url = article_author_info.xpath('./a[1]/@href').extract_first()
# 获取当前文章的发布日期
article_publish_date = article_author_info.xpath('./span[1]/span/text()').extract_first()
# 获取当前文章的点赞数
article_up_num = article_author_info.xpath('./a[2]/span/text()').extract_first()
# 获取当前文章的评论数
article_comment_num = article_author_info.xpath('./a[3]/span/text()').extract_first()
# 获取当前文章的阅读数
article_read_num = article_author_info.xpath('./a[4]/span/text()').extract_first()
# 构造当前文章的字典信息
data = {
"article_title": article_title,
"article_link": article_link,
"article_desc": article_desc,
"article_author_name": article_author_name,
"article_author_avatar_url": article_author_avatar_url,
"article_author_url": article_author_url,
"article_publish_date": article_publish_date,
"article_up_num": article_up_num,
"article_comment_num": article_comment_num,
"article_read_num": article_read_num,
"article_content": ""
}
# print(data)
# 向管道中提交数据 : 注意这里是抓到一条提交一条,也可以全部抓取后批量处理
item.update(data)
# print(article_link)
# meta : 携带 item 对象给 detail_parse 解析后向内部追加内容
# 在当前数据基础上添加详情
yield Request(url=article_link, callback=self.detail_parse, meta={'item': item})
# 获取下一页的链接地址
# 下一页的链接地址在最底部的最右侧
next_url = 'https://www.cnblogs.com' + response.xpath(
'//div[contains(@class,"pager")]/a[last()]/@href').extract_first()
# print(next_url)
# callback 参数是控制返回response后使用的解析方法
# 下一页地址,继续爬取,解析还是用parse
yield Request(url=next_url, callback=self.parse)
# Response对象:detail_parse中,通过response取出meta取出item,把文章详情写入
def detail_parse(self, response):
# 获取到原来的 item 对象
item = response.meta.get('item')
print(item)
# 解析到文章详情
content = str(response.xpath('//div[@id="cnblogs_post_body"]').extract_first())
# 继续向 item 对象中追加文章详情内容
item['content'] = content
# 将 item 对象提交给管道
yield item
【七】中间件
1)爬虫中间件
- middlewares.py
1.from_crawler
-
from_crawler 方法是一个类方法,它会在创建爬虫实例时被Scrapy调用,用于初始化爬虫中间件的实例。
@classmethod def from_crawler(cls, crawler): # 该方法是Scrapy用于创建爬虫实例的方法。 # 首先创建了一个中间件实例 `s` s = cls() # 然后通过 `crawler.signals.connect` 方法连接了 `spider_opened` 信号和对应的处理方法。 crawler.signals.connect(s.spider_opened, signal=signals.spider_opened) return s
2.process_spider_input
-
process_spider_input 方法会在响应从爬虫中间件传递到爬虫之前调用。
-
可以用来对响应进行预处理或检查
def process_spider_input(self, response, spider): # 当响应从爬虫中间件进入爬虫时,调用该方法进行处理。 # response: 是响应对象 # spider: 是当前爬虫实例 # 应该返回 `None` 或引发异常 return None
3.process_spider_output
-
process_spider_output 方法在爬虫处理完响应后会被调用。
-
主要用于对爬虫处理结果进行进一步处理或过滤,并将处理结果返回
-
必须返回一个可迭代的Request对象或item对象。
def process_spider_output(self, response, result, spider): # 当爬虫处理完响应后,调用该方法对处理结果进行处理。 # response 是爬虫处理后的响应对象 # result 是爬虫的处理结果 # spider 是当前爬虫实例 # 必须返回一个可迭代的Request对象或item对象。 for i in result: yield i
4.process_spider_exception
-
process_spider_exception 方法在爬虫或 process_spider_input() 方法中抛出异常时会被调用。
-
这个方法可以用来对爬虫处理过程中的异常进行处理
-
可以返回 None 或一个可迭代的Request对象或item对象。
def process_spider_exception(self, response, exception, spider): # 当爬虫中抛出异常时,调用该方法进行处理。 # response 是发生异常的响应对象 # exception 是抛出的异常对象 # spider 是当前爬虫实例。 # 应返回None或者一个可迭代的Request对象或item对象。 pass
5.process_start_requests
-
process_start_requests 方法在爬虫启动时被调用
-
用于对初始请求进行处理。
-
这个方法必须返回一个可迭代的Request对象,而不能返回ite对象。
def process_start_requests(self, start_requests, spider): # 在爬虫启动时,对初始请求进行处理。 # start_requests 是初始请求的列表 # spider 是当前爬虫实例 # Must return only requests (not items). for r in start_requests: yield r
6.spider_opened
-
spider_opened 方法在爬虫打开时被调用。
-
在这个方法中,通过日志记录器(logger)输出 "Spider opened: 爬虫名称" 的信息。
def spider_opened(self, spider): # spider: 表示当前爬虫实例 spider.logger.info("Spider opened: %s" % spider.name)
【八】集成Selenium框架
1)定义浏览器对象
- 在爬虫类中写
from selenium import webdriver
class CnblogsSpider(scrapy.Spider):
# 实例化WebDriver,这里以Chrome为例
bro = webdriver.Chrome()
bro.implicitly_wait(10)
def close(spider, reason):
spider.bro.close() #浏览器关掉
2)定义中间件处理
- 在中间件中
from scrapy.http.response.html import HtmlResponse
def process_request(self, request, spider):
# 爬取下一页这种地址---》用selenium,但是文章详情,就用原来的
if 'sitehome/p' in request.url:
print(request.url)
# 调用父类的 browser 对象 对目标地址发起请求
spider.browser.get(request.url)
# 导入 Scrapy 内置的响应数据解析器解析页面数据
from scrapy.http.response.html import HtmlResponse
# 创建一个 HtmlResponse 对象,并设置其 body 属性为浏览器对象获取到的页面数据
response = HtmlResponse(url=request.url, body=bytes(spider.browser.page_source, encoding='utf-8'))
# 返回解析后的响应对象
return response
else:
return None
3)开启中间件
DOWNLOADER_MIDDLEWARES = {
"SpiderFirst.middlewares.SpiderfirstDownloaderMiddleware": 543,
}
【九】请求头操作
1)使用代理
- 在下载中间件写process_request方法
def get_proxy(self):
import requests
res = requests.get('http://127.0.0.1:5010/get/').json()
if res.get('https'):
return 'https://' + res.get('proxy')
else:
return 'http://' + res.get('proxy')
def process_request(self, request, spider):
request.meta['proxy'] = self.get_proxy()
return None
- 代理可能不能用,会触发process_exception,在里面写
def process_exception(self, request, exception, spider):
# 第二步:代理可能不能用,会触发process_exception,在里面写
def process_exception(self, request, exception, spider):
print('-----', request.url) # 这个地址没有爬
return request
2)携带Cookie
def process_request(self, request, spider):
# 添加cookie
request.cookies['cookies'] = 'cookies'
print(request.url+':请求对象拦截成功!')
return None
3)携带请求头
def process_request(self, request, spider):
request.headers['referer'] = 'http://www.lagou.com'
return None
4)随机UA
# fake_useragent模块
from fake_useragent import UserAgent
# 动态生成User-agent使用
def process_request(self, request, spider):
request.headers['User-Agent']=str(UserAgent().random)
print(request.url+':请求对象拦截成功!')
return None
标签:框架,self,爬虫,spider,item,Scrapy,64,article,scrapy
From: https://www.cnblogs.com/Mist-/p/18336148