爬虫实战_Scrapy框架

Scrapy是用Python语言编写,通过Twisted异步网络框架提升下载速度,是一个快速、高层次的屏幕抓取和Web抓取框架,常用于数据挖掘、监测和自动化测试等。

一、Scrapy框架介绍

Scrapy内部实现了并发请求、免登录、URL去重等操作,开发者可根据自己的需求去编写部分代码,就能抓取到所需要的数据。Scrapy框架包含的组件有调度器、下载器、Scrapy引擎、项目管道、爬虫以及各中间件等。

Scrapy框架爬取流程:首先从初始URL开始,调度器会将其交给下载器(Downloader),下载器向网络服务器发送请求进行下载,得到的响应后将下载数据交给爬虫,爬虫会对网页进行分析,分析出来的结果有两种:一种是需要进一步抓取的链接,这些链接会被传回调度器,另一种是需要保存的数据,它们会被传送至项目管道,项目管道进一步对数据进行清洗、去重等处理,并存储到文件或数据库中。数据爬取过程中,Scrapy引擎用于控制整个系统的数据处理流程。

Scrapy框架内包含的各组件功能如下:

Scrapy引擎:用来控制整个系统的数据处理流程,并进行事务处理的触发。

调度器中间件:位于Scrapy引擎和调度器之间,主要用于处理Scrapy引擎发送到调度器的请求和响应。

调度器:用来接收引擎发送过来的请求,压入队列完成去重操作,并决定下一个要抓取的网站,在引擎再次请求的时候返回URL。

下载器中间件:位于Scrapy引擎和下载器之间,主要用于处理Scrapy引擎与下载器之间的请求及响应,其中代理IP和用户代理可以在这里设置。

下载器:用于下载网页内容,并将网页响应结果返回给爬虫。

爬虫中间件:位于Scrapy引擎和爬虫之间,主要用于处理爬虫的响应输入和请求输出。

爬虫:用于从特定网页中提取需要的信息,也可以从中提取URL交给调度器,让Scrapy继续爬取下一个页面。

项目管道:负责处理爬虫从网页中抓取的信息,主要的功能为持久化项目、验证项目的有效性、清除不需要的信息,并完成数据存储。

二、爬虫实战

1.项目需求

基于Scrapy框架爬取某网站的新闻标题和内容。

2.分析页面网站

通过网页解析,了解新闻网站不同模块对应的详情页URL均为静态数据。

通过对不同板块的网页进行解析,了解各模块的新闻为动态加载数据,且新闻标题位于“a”标签下。

进一步,分析新闻网页,了解新闻内容位于“p”标签下。

3.项目搭建

第一步:创建项目

Pycharm终端输入

cd 框架 #进入项目文件夹路径scrapy startproject wangyi #创建项目,wangyi为项目名cd wangyi #进入项目路径scrapy genspider spiderName www.xxx.com #在子目录中创建爬虫文件

项目结构如下:spiders用于存放爬虫程序(SpiderName.py)的文件夹;items用来定义数据结构,类似于字典的功能;middlewares中间件,可设置ip代理等;pipelines用于对items中的数据进行清洗、存储等操作;settings是设置文件,包含爬虫项目的信息;scrapy.cfg是关于项目配置文件。

第二步:编写爬虫代码(spiderName.py)

import scrapyfrom selenium import webdriverfrom wangyi.items import WangyiItemclass WangyiSpider(scrapy.Spider):name = wangyi#allowed_domains = [www.xxx.com]start_urls = []models_urls = [] #存储五个板块的详情页url#实例化浏览器对象def __init__(self):self.bro = webdriver.Chrome(executable_path=D:/PyCharm/learnpython/框架/wangyi/chromedriver.exe)def parse(self, response):li_list = response.xpath(//*[@id="index2016_wrap"]/div[2]/div[2]/div[2]/div[2]/div/ul/li)alist = [2,3,5,6,7]for index in alist:model_url = li_list[index].xpath(./a/@href).extract_first()self.models_urls.append(model_url)#依次对每一个板块对应的页面发送请求for url in self.models_urls:yield scrapy.Request(url,callback=self.parse_model)def parse_model(self,response):div_lists = response.xpath(/html/body/div/div[3]/div[4]/div[1]/div[1]/div/ul/li/div/div)for div in div_lists:title = div.xpath(./div/div[1]/h3/a/text()).extract_first()new_detial_url = div.xpath(./div/div[1]/h3/a/@href).extract_first()item = WangyiItem()            item[title] = titleyield scrapy.Request(url=new_detial_url , callback=self.parse_detial , meta={item : item})def parse_detial(self,response):content = response.xpath(//*[@id="content"]/div[2]//text()).extract()content = .join(content)item = response.meta[item]item[content] = contentyield itemdef closed(self,spider):        self.bro.quit()

注意不能使用return返回数据,应使用yield返回数据。使用return直接退出函数,而对于yield在调研for的时候,函数内部不会立即执行,只是返回一个生成器对象。

第三步:设置中间件(middlewares.py)

from scrapy import signalsfrom scrapy.http import HtmlResponsefrom time import sleep# useful for handling different item types with a single interfacefrom itemadapter import is_item, ItemAdapterclass WangyiDownloaderMiddleware:    def process_request(self, request, spider):        return None#通过该方法拦截五大板块对应的响应对象,进行纂改def process_response(self, request, response, spider):#挑选出指定的响应对象精选纂改bro = spider.bro #获取在爬虫类中定义的浏览器对象if request.url in spider.models_urls:bro.get(request.url) #五个板块url发送请求sleep(2)page_text = bro.page_source #动态加载的新闻数据new_response = HtmlResponse(url=request.url,body= page_text,encoding=utf-8,request=request)return new_responseelse:return response    def process_exception(self, request, exception, spider):pass

第四步:数据存储

定义爬取数据结构(items.py)

import scrapyclass WangyiItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()title = scrapy.Field()content = scrapy.Field()    pass

定义数据管道(pipelines.py)

class WangyiPipeline:    fp = None# 重写父类的一个方法,该方法只会在开始爬虫的时候被调用一次def open_spider(self, spider):print(开始爬虫。。。。。。)self.fp = open(./wangyi.text, w, encoding=utf-8)# 用来专门处理item类型对象# 该方法每接收到一个item就会被调用一次def process_item(self, item, spider):title = item[title]content = item[content]self.fp.write(title + : + content + \n)print(item)return itemdef close_spider(self, spider):print(结束爬虫。。。。。。)        self.fp.close()

第五步:程序配置(settings.py)

UA伪装

USER_AGENT = Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36

对robots协议的遵守进行修改

ROBOTSTXT_OBEY = False

显示指定类型日志信息

LOG_LEVEL =ERROR

开启中间件

DOWNLOADER_MIDDLEWARES = { wangyi.middlewares.WangyiDownloaderMiddleware: 543,}

开启管道

ITEM_PIPELINES = { wangyi.pipelines.WangyiPipeline: 300,}

第六步:执行项目

Pycharm终端输入

scrapy crawl wangyi #wangyi 为爬虫项目名

4.爬虫结果

参考资料:

《Python网络爬虫技术与实战》,2021,赵国生、王健著。

注:本文仅供学术交流,不提供完整代码。如有侵权,请联系我,第一时间删除。