首页 > 其他分享 >64.Scrapy框架

64.Scrapy框架

时间:2024-08-01 10:43:22浏览次数:11  
标签:框架 self 爬虫 spider item Scrapy 64 article scrapy

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

相关文章

  • 63.Selenium框架
    Selenium框架【一】浏览器操作1)页面操作1.初始化浏览器对象#使用环境变量fromseleniumimportwebdriverbrowser=webdriver.Chrome()browser=webdriver.Chrome(path)browser.close() #关闭浏览器#使用绝对路径fromselenium.webdriver.chrome.serviceimport......
  • 微软GraphRAG框架源码解读(LLMs)
    1.引言这几天微软开源了一个新的基于知识图谱构建的检索增强生成(RAG)系统:GraphRAG。该框架旨在利用大型语言模型(LLMs)从非结构化文本中提取结构化数据,构建具有标签的知识图谱,以支持数据集问题生成、摘要问答等多种应用场景。GraphRAG的一大特色是利用图机器学习算法针对数据......
  • 1、消息队列框架:ActiveMQ - 开源项目研究文章
    ActiveMQ是Apache软件基金会下的一个开源消息队列服务,遵循JMS1.1规范(JavaMessageService),是一种面向消息中间件(MOM)的实现。它提供高可用性、出色的性能、可扩展性、稳定性和安全性的消息传递服务。ActiveMQ的架构ActiveMQ的架构包括生产者(Producer)、消费者......
  • 1、.Net UI框架:UWP - .Net宣传系列文章
    UWP(UniversalWindowsPlatform)是微软推出的一种应用程序开发平台,它允许开发者创建能够在各种Windows10设备上运行的应用程序,包括PC、平板、手机、Xbox、HoloLens等。UWP是Windows10操作系统的核心组件之一,它提供了统一的API和开发工具,使得开发者能够编写一次代码,然后在多个......
  • scrapy在pychram中调试
    方法一#Name:配置项目的名称#Scriptpath:scrapypackage中的cmdline.py文件路径#Parameters:启动scrapy爬虫所需参数(也就是传参)#PythonInterpreter:选择所用的Python环境(我用的自己创建的anaconda虚拟环境,找cmdline.py文件时也是在虚拟环境中的site-packages找到,这点要注意)......
  • 工作流流程引擎框架推荐来了
    近期有不少粉丝客户朋友都在询问工作流流程引擎框架推荐。随着行业竞争激烈化,实现流程化办公已经成为当务之急。低代码技术平台及工作流流程引擎拥有够灵活、更可靠、可视化界面等诸多个优势特点,在推动企业实现数字化转型的过程中深受行业信赖与喜爱。接下来就一起看看工作流流程......
  • 手写 Hibernate ORM 框架 05-基本效果测试
    手写Hibernate系列手写HibernateORM框架00-hibernate简介手写HibernateORM框架00-环境准备手写HibernateORM框架01-注解常量定义手写HibernateORM框架02-实体Bean定义,建表语句自动生成手写HibernateORM框架03-配置文件读取,数据库连接构建手写Hi......
  • Spring框架 配置Gateway网关/spring cloud gateway 基础入门案例教程
    文章目录目录文章目录安装流程小结概要安装流程技术细节小结概要网关作为微服务集群唯一的对外入口,可以实现很多功能.例如:统一的解决跨域(一个ajax请求origin域名和请求目标url中域名不同,ip不同,域名不同,端口不同,都会引发的问题)问题.统一的身份认证.认证解......
  • 【Unity源码】Auto Chess: 自走棋策略游戏开发框架
    在UnityAssetStore上,一款名为"AutoChess"的资源包为开发者提供了一个完整的框架,以便快速构建和部署自己的自走棋游戏。自走棋是一种结合了策略、卡牌和棋盘游戏元素的流行游戏类型,而这个资源包让开发者能够轻松地将这一概念实现在Unity项目中。资源包亮点全面的......
  • 笔记:从Aurora 8b/10b 到Aurora 64b/66b (一):64b/66b 基本知识
    参考搬运:https://mp.weixin.qq.com/s/ZSNyjpZpimjyxyO9riIRNQAurora64B/66B(xilinx.com)https://docs.amd.com/r/en-US/pg074-aurora-64b66b8/10:SATASRIO64/66:10G以太网值得注意:64b/66b编码在多LANE模式下,EOF(T)仅在一个LANE上出现;介绍8B10B的开销比较大,每传输10位数......