爬虫实战:Scrapy框架

优采云 发布时间: 2022-05-01 01:16

  爬虫实战: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 WangyiItem<br />class WangyiSpider(scrapy.Spider): name = 'wangyi' #allowed_domains = ['www.xxx.com'] start_urls = ['https://news.163.com/'] 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)<br /> 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'] = title yield 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'] = content yield item<br /> def 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, ItemAdapter<br />class 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_response else: return response<br />    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')<br /> # 用来专门处理item类型对象 # 该方法每接收到一个item就会被调用一次 def process_item(self, item, spider): title = item['title'] content = item['content'] self.fp.write(title + ':' + content + '\n') print(item) return item<br /> def 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,赵国生、王健著。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线