python爬虫--Scrapy框架--Scrapy+selenium实现动态爬取

2023-11-10

python爬虫–Scrapy框架–Scrapy+selenium实现动态爬取

前言

本文基于数据分析竞赛爬虫阶段,对使用scrapy + selenium进行政策文本爬虫进行记录。用于个人爬虫学习记录,可供参考,由于近期较忙,记录得较粗糙,望见谅。

框架结构

start启动scrapy -> 爬虫提交链接request(可以有多条链接)给Scheduler -> Scheduler决定链接的调度(调度器应该是个优先队列,起到分配线程的作用,用分布式爬虫来加快爬取速度)-> Scheduler把请求的链接发送给下载器(下载器可以配置middlewares) -> 下载器发送request给网页服务器 -> 网络服务器将response对象返回给下载器 -> 下载器将response下载发送给爬虫 -> 爬虫解析response返回的对象并进行后续操作(给Item Pipeline发送存储请求or再次发起链接请求)

Scrapy Engine进行整个爬虫流程的把控,相当于一个main函数。Scrapy流程示意图如下图所示:

创建爬虫

cd <项目文件夹>
scrapy startproject SpiderProjectName
... ...
cd SpiderProjectName
# 创建普通爬虫
scrapy genspider spider_name xxx.com
# 创建crawlspider(可定义抓取规则,自动抓取链接)
scrapy genspider -t crawl spider_name xxx.com

配置settings

  • 不遵循爬虫协议(建议改成False)
ROBOTSTXT_OBEY = False

当要用到下面的构件时,在settings.py中找到下面代码,去掉#号即可

  • 开启中间件
# 开启下载器中间件
DOWNLOADER_MIDDLEWARES = {
    'testSpider.middlewares.TestspiderDownloaderMiddleware': 543,
}
# 开启爬虫中间件
SPIDER_MIDDLEWARES = {
    'testSpider.middlewares.TestspiderSpiderMiddleware': 543,
}
  • 设置header
DEFAULT_REQUEST_HEADERS = {
   'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
   'Accept-Language': 'en',
   'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36' # 填写自己的请求头,自己的是这个
}
  • 开启pipelines
ITEM_PIPELINES = {
    'testSpider.pipelines.TestspiderPipeline': 300,
}
  • 设置下载时延,防止爬虫被识别
DOWNLOAD_DELAY = 3 # 默认是3
RANDOMIZE_DOWNLOAD_DELAY=True # 这行要自己加,在settings中没有定义
  • 关闭COOKIES,防止服务器追踪爬虫轨迹
# Disable cookies (enabled by default)
COOKIES_ENABLED = False

重写方法

  • 定义开始爬取的链接一般写在spider.py的start_urls中。如果需要写一个方法来生成链接,可以在你的spider.py文件里重写start_requests(self)方法。

自定义中间件

在middlewares中重写中间件方法,可以实现自己的功能(例如利用selenium进行模拟点击)。

Downloader和Spider中间件都需要先在settings.py中先开启。如果自己在middlewares中定义了新的中间件class,则应在settings中自行添加类名和权重值。权重值越小,越优先执行。

DOWNLOADER_MIDDLEWARES = {
    'testSpider.middlewares.TestspiderDownloaderMiddleware': 543,
    'testSpider.middlewares.CustomDownloaderMiddleware': 542, # 先执行权值小的
    'testSpider.middlewares.RandomUserAgentMiddleware': 541, # 开启假请求头的下载器中间件	
}
  • 设置多请求头(假请求头)

为了防止scrapy被识别,可以使用多(假)请求头来发送请求
如上,在DOWNLOADER_MIDDLEWARES中

from fake_useragent import UserAgent
import random

class RandomUserAgentMiddleware(object):
    def __init__(self):
        self.agent = UserAgent()

    @classmethod
    def from_crawler(cls, crawler):
        return cls()

    def process_request(self, request, spider):
        user_agent = self.agent.random
        request.headers.setdefault('User-Agent', user_agent)
        print(user_agent)

item类–自定义meta字段

预定义元数据,告诉爬虫item中有的字段。

  • items.py
class TestspiderItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    url = scrapy.Field()
    date = scrapy.Field()
    title = scrapy.Field()
    content = scrapy.Field()
  • spider.py
from TestspiderSpider.items import TestspiderItem
    def parse_item(self, response):
        url = response.url
        date = response.xpath('/html/head/meta[@name="PubDate"]/@content').get()[:-6]
        title = response.xpath('/html/head/meta[@name="ArticleTitle"]/@content').get()
        content = response.xpath('//*[@class="content-text"]').get()
        yield TestspiderItem(url=url, date=date, title=title, content=content)

配合selenium实现动态爬取

  • scrapy可以高效实现页面抓取,scrapy的crawlspider类可以自动抓取链接并前往链接解析内容。
  • selenium可以实现动态点击,能够获得加载完整的page_source,与scrapy互补。

selenium的安置方法

selenium能够负责解析动态页面,返回动态生成的网络源码。但是selenium应该放在能够实现动态点击,且能够返回动态生成的源码的地方。因此,selenium的安放有讲究,目前我只发现这一种方法,后续如果有更好的方法再补充。

放在middlewares的process_request()

爬虫将url传入到middlewares,因此可以在middlewares的process_request()方法中向服务器发送操作请求,再用driver.page_source解析网页源码,此时服务器response的源码加载了动态生成的内容。

  • 爬虫每发送一次url请求,process_request()调用一次。如果要加载动态内容,selenium可以安放在这里。

注意

spider.py的start_requests()方法yield Request(url)的只是一个链接请求,并不是动态生成的内容,默认还是加载起始字段;

crawlspider

crawlspider只能抓取response返回的源码中符合Rule的链接,再访问链接里的内容。

  • crawlspider继承了scrapy.spider的CrawlSpider类,该类中多了一个名为rules的成员变量,定义了抓取规则
  • 对于满足rules的链接,crawlspider会再次将这些链接向middlewares发送request,因此middlewares中的process_request, process_response方法也会再次调用
  • Rule()里定义LinkExtractor规则,LinkExtractor()方法参数常用的有:allow:只有正则匹配成功的链接才捕获;restrict_xpath:规定xpath格式的链接才捕获

问题

如何才能在start_url中动态点击按钮获得下一个链接的同时,解析数据返回给爬虫,同时selenium能够在当前页面继续爬取(比如要爬取新闻文本,点击下一页按钮(按钮是js加载,因此没有链接),生成了新的页面,抓取新页面的新闻链接后,再在该页面基础上点击下一页面获得新页面源码)?

补充:process_request不能采用yield方法,因为yield方法返回的是一个包装了链接的生成器(generator)对象,而不是普通的链接,scrapy是处理不了这种对象的。

解决方案

目前我还没有在scrapy中能一次性解决上面的问题的方法,我最终决定selenium和scrapy分开来处理。这个方法比较笨,但也是无奈之举= =。毕竟爬取这个网站确实是比较麻烦。如果有更好的方法,后续会继续补充。

思路:将爬虫分成两步:
一、先用selenium爬取所有项目对应的所有链接,并存储到数据库中。数据库设计如下

post_url category

二、在start_requests方法中,按page yield成新界面的url对爬虫发送请求。对于发送的页面链接,在process_request用selenium进行driver.get(request.url)方法处理,并return HtmlResponse(url, body = self.driver.page_source, request = request, encoding = 'utf-8')。此时返回的页面是动态加载生成的页面,用crawlspider自动捕获新闻链接,并重新向爬虫发送请求,获得的新闻链接在parse方法中进行处理。

此时爬虫的工作就已经完成,后续只需将parse中将新闻链接中要提取的数据打包成item,记住要保留他的post_url,将打包好的item返回给pipeline,保存到数据库中。该步数据库设计如下:

post_url date title content

将第一和第二步存储的数据库按照post_url进行连接,就可以得到所需要的文本信息了。此时爬虫工作成功完成。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python爬虫--Scrapy框架--Scrapy+selenium实现动态爬取 的相关文章

随机推荐

  • 工作学习之余如何学习Python?

    作为一个学生 可能平常除了上课也没有很多别的时间了 今天就给大家分享一下 工作学习之余 应该如何学习Python 1 明确目标 对于零基础的人而言 要明确你学习Python仅仅是为了满足好奇心 还是有工作需要 比如办公自动化的需要 转行的需
  • 史上最强最全网站资源整理

    一 找资源利器 胖次 http www panc cc 爱挖盘 http www iwapan com 盘多多 http www panduoduo net 盘窝窝 http www panww com 百度网盘搜索 http uzi8 c
  • Qt3.6.3编译pc版本的时候:collect2:ld terminated with signal 11

    Qt3 6 3编译pc版本的时候 collect2 ld terminated with signal 11 原因 是swap交换空间不够用 解决 扩大虚拟内存 具体参考下文 http hi baidu com seaeechou blog
  • PCB高速信号布线技巧

    转载 玩转嵌入式 2021 07 31 18 59 电源布局布线 数字电路很多时候需要的电流是不连续的 所以对一些高速器件就会产生浪涌电流 如果电源走线很长 则由于浪涌电流的存在进而会导致高频噪声 而此高频噪声会引入到其他信号中去 而在高速
  • gdb调试驱动模块

    众所周知 要想使用gdb调试 那么在编译的时候一定要加上 g选项 因为编译器默认是不加 g选项的 因此在编译模块的时候 我们需要在Makefile里面添加如下信息 EXTRA CFLAGS g 在添加了上面的信息后 我们编译出来的 ko文件
  • yolo.h5文件问题的解决 - 吴恩达深度学习:目标检测之YOLO算法

    在吴恩达深度学习系列视频 卷积神经网络第三周作业中 加载预训练模型时 yolo model load model model data yolo h5 你会遇到yolo h5文件找不到的情况 而当你去网上下载了一个yolo h5文件时 可能
  • Java解一元二次方程

    import java util Scanner public class Calculate public static void main String args 创建键盘录入 Scanner sc new Scanner System
  • 网站搭建——Linux服务器环境搭建

    网站搭建 Linux服务器环境搭建 网站搭建 Linux服务器环境搭建 一 MySQL8安装 1 卸载MariaDB 2 下载 3 解压 4 安装MySql包 5 启动MySql 5 MySql临时密码 6 MySql设置 7 MySql登
  • kotlin支持Android低版本吗,如何从Android项目中删除Kotlin支持?

    步骤1 从build gradle Project 文件中删除或注释掉这些行 ext kotlin version 1 1 51 My kotlin version might be different from yours classpa
  • 如何用Nodejs写接口

    有时候前端需调用接口测试功能 但是相关的接口还没有开发好 或者没有相应的数据 这时候怎么办呢 这里教大家使用nodejs express写自己的接口 首先安装express cnpm install express save 然后新建js文
  • 9 种方法使用 Amazon CodeWhisperer 快速构建应用

    Amazon CodeWhisperer 是一款很赞的生成式人工智能编程工具 自从在工作中使用了 CodeWhisperer 我发现不仅代码编译的效率有所提高 应用开发的工作也变得快乐起来 然而 任何生成式 AI 工具的有效学习都需要初学者
  • redis的5种数据类型

    1 redis的5种数据类型 string 字符串 可以为整形 浮点型和字符串 统称为元素 list 列表 实现队列 元素不唯一 先入先出原则 set 集合 各不相同的元素 hash hash散列值 hash的key必须是唯一的 sort
  • 动态规划+状态压缩思路解决旅行者问题

    问题描述 小明目前在做一份毕业旅行的规划 打算从北京出发 分别去若干个城市 然后再回到北京 每个城市之间均乘坐高铁 且每个城市只去一次 由于经费有限 希望能够通过合理的路线安排尽可能的省一些路上的花销 给定一组城市和每对城市之间的火车票的价
  • 区块链技术在日常生活有那些影响?

    区块链首先是一种社会思潮 它预示着人类社会转型 换代的新时代的到来 区块链的技术基础是分布式网络架构 正是因为分布式网络技术的成熟 去中心 弱中心 分中心及共享 共识 共担的组织架构 商业架构和社会架构才有可能有效建立起来 大概就是从工程技
  • js实现约瑟夫问题(数目的游戏问题编程)

    17世纪的法国数学家加斯帕在 数目的游戏问题 中讲了这样一个故事 15个教徒和15 个非教徒在深海上遇险 必须将一半的人投入海中 其余的人才能幸免于难 于是想了一个办法 30个人围成一圆圈 从第一个人开始依次报数 每数到第九个人就将他扔入大
  • 将一个整数逆序输出·正序输出它的每一位数字

    逆序输出n的每位数字 void PrintReverse int n 定义一个函数 他的数据类型为整型 if n lt 0 printf n n 对于负数的整数 改变输出 的多少 do printf d n 10 当n不等于0时 n对10取
  • JAVA不可达代码

    说明这句代码之前有一个死循环 解决方法 一般是需要将代码放入死循环代码中 并设定一个停止循环代码的条件
  • golang jsoniter extension 处理动态字段

    1 背景 golang 原生 json 包 在处理 json 对象的字段的时候 是需要严格匹配类型的 但是 实际上 当我们与一些老系统或者脚本语言的系统对接的时候 有时候需要对类型需要做一下兼容 假设我们有以下需求 目标类型 输入 解析后
  • 图灵奖得主Judea Pearl:因果推断论文本周推荐(2022.8.8)

    刚刚 图灵奖得主 因果科学之父Judea Pearl 在推特上推荐了本周值得一读的10篇近期发表的因果推断相关论文 推荐列表下载 他评价道 他看到了人们对于 公平 责任 主题的兴趣日益浓厚 为帮助大家快速了解这些文章的主旨内容 我将推荐列表
  • python爬虫--Scrapy框架--Scrapy+selenium实现动态爬取

    python爬虫 Scrapy框架 Scrapy selenium实现动态爬取 前言 本文基于数据分析竞赛爬虫阶段 对使用scrapy selenium进行政策文本爬虫进行记录 用于个人爬虫学习记录 可供参考 由于近期较忙 记录得较粗糙 望