• Python爬虫框架Scrapy的用法
  • 发布于 2个月前
  • 289 热度
    0 评论
运行环境 Runtime environment
操作系统: Windos10  
IDE: pycharm 2021.3.1 x64  
语言: python v3.9.1

框架: Scrapy v2.4.1


背景
应用场景,站源的数据是按照日期区间(一年的第一天到该年的最后一天),来进行检索,根据结果整合成 url 列表来进行采集。那么,这个列表中的 url 数量就会相当的庞大。倘若对它进行切分,用多个相同的 Scrapy 爬虫,来对切分好的各个分段 url 进行采集,加上 scrapy 自身的并发,那采集速度就可以指数倍增长。

当然,这也会消耗性能,对服务器的配置要求也会提高,代理 IP 消耗量也会增加。就算使用批量插入数据,可能也会把 mysql干爆。Scrapy 是线程级别,实现异步。使用多个进程,来多次跑 Scrapy 爬虫。为了避免本文篇幅过长,仅介绍如何多进程跑 scrapy,不介绍如何切分 url 列表,让 scrapy 区间采集。

multiprocessing 模块介绍
python 中的多线程无法利用多核优势,如果想要充分地使用多核 CPU 的资源(os.cpu_count () 查看),在 python 中大部分情况需要使用多进程。Python 提供了 multiprocessing。 multiprocessing 模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模块 threading 的编程接口类似。

multiprocessing 模块的功能众多:支持子进程、通信和共享数据、执行不同形式的同步,> 提供了 Process、Queue、Pipe、Lock 等组件。需要再次强调的一点是:与线程不同,进程没有任何共享状态,进程修改的数据,改动仅限于该进程内。

Scrapy 框架的介绍
Scrapy, 这把刀是我的最爱。作为一个易上手的高性能爬虫框架,Scrapy 使用 Twisted 异步网络框架处理并发请求。Scrapy 诞生得比较早,核心通过 yield 这一携程的思路来实现的异步。虽然 Twisted 框架提供了线程池支持,但是其核心网络部分处理逻辑依赖的是「单线程 IO 多路复用」技术,在 Linux 平台上,是围绕 epoll () 系统调用实现的 Reactor 模式。

总有人说,Scrapy 不灵活,限制太多来作为缺点来评价它,但是却没几个人能好好举出究竟具体是什么场景 Scrapy 不能胜任的案例。摸棱两可的跟风评价,没有什么营养。在这里并不是说 Scrapy 是如何完美的框架,它确实有自己的缺点,但是..

绝大多数情况下,都是因为自己对框架没有足够的了解和自身缺乏开阔的开发思维。多人协作开发的情况,统一的框架结构,更易于维护。

部分代码
scrapy 的爬虫文件
# 堆代码 duidaima.com
# -*- coding: utf-8 -*-
import scrapy
from multiprocessing import Process
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings

class BaiduSpider(scrapy.Spider):
    name = 'baidu'
    allowed_domains = ['baidu.com']

    def __init__(self, category=None, *args, **kwargs):
        super(BaiduSpider, self).__init__(*args, **kwargs)
        self.start_urls = f"https://www.baidu.com/s?ie=utf-8&wd={category}"

    def start_requests(self):
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36',
        }
        yield scrapy.Request(self.start_urls, headers=headers, callback=self.parse)

    def parse(self, response):
        print(response.status)
        # print(response.text)

def start(category):
    print(f"category={category}")
    settings = get_project_settings()
    process = CrawlerProcess(settings)
    spider = BaiduSpider()
    process.crawl(spider, category=category)
    process.start()

if __name__ == "__main__":
    name = ['java', 'python', 'C语言', 'php', 'goland']
    for i in range(len(name)):
        category = name[i]
        p = Process(target=start, args=(category,))
        p.start()
这段代码要做的是:
1.使用百度搜索 [‘java’, ‘python’, ‘C 语言’, ‘php’, ‘goland’] 这些关键字
2.采集搜索到的结果列表。
3.使用 multiprocessing 的 Process 封装,多次运行 Scrapy
4.为每一个关键词,单独跑一个关键词。即’java’跑一个 Scrapy,’python’跑一个 Scrapy…

5.而不是一个 scrapy 跑 [‘java’, ‘python’, ‘C 语言’, ‘php’, ‘goland’] 所有关键词搜索结果


总结
代码中,有 get_project_settings 和 CrawlerProcess 方法的应用。在封装 scrapy 启动文件的时候,可以更加的优雅。
用户评论