发布:2023/12/7 16:14:55作者:管理员 来源:本站 浏览次数:669
用Python获取网络数据
网络数据采集是 Python 语言非常擅长的领域,上节课我们讲到,实现网络数据采集的程序通常称之为网络爬虫或蜘蛛程序。即便是在大数据时代,数据对于中小企业来说仍然是硬伤和短板,有些数据需要通过开放或付费的数据接口来获得,其他的行业数据和竞对数据则必须要通过网络数据采集的方式来获得。不管使用哪种方式获取网络数据资源,Python 语言都是非常好的选择,因为 Python 的标准库和三方库都对网络数据采集提供了良好的支持。
requests库
要使用 Python 获取网络数据,我们推荐大家使用名为requests 的三方库,这个库我们在之前的课程中其实已经使用过了。按照官方网站的解释,requests是基于 Python 标准库进行了封装,简化了通过 HTTP 或 HTTPS 访问网络资源的操作。上课我们提到过,HTTP 是一个请求响应式的协议,当我们在浏览器中输入正确的 URL(通常也称为网址)并按下 Enter 键时,我们就向网络上的 Web 服务器发送了一个 HTTP 请求,服务器在收到请求后会给我们一个 HTTP 响应。在 Chrome 浏览器中的菜单中打开“开发者工具”切换到“Network”选项卡就能够查看 HTTP 请求和响应到底是什么样子的,如下图所示。
通过requests库,我们可以让 Python 程序向浏览器一样向 Web 服务器发起请求,并接收服务器返回的响应,从响应中我们就可以提取出想要的数据。浏览器呈现给我们的网页是用 HTML 编写的,浏览器相当于是 HTML 的解释器环境,我们看到的网页中的内容都包含在 HTML 的标签中。在获取到 HTML 代码后,就可以从标签的属性或标签体中提取内容。下面例子演示了如何获取网页 HTML 代码,我们通过requests库的get函数,获取了搜狐首页的代码。
import requests
resp = requests.get('https://www.sohu.com/')
if resp.status_code == 200:
print(resp.text)
说明:上面代码中的变量resp是一个Response对象(requests库封装的类型),通过该对象的status_code属性可以获取响应状态码,而该对象的text属性可以帮我们获取到页面的 HTML 代码。
由于Response对象的text是一个字符串,所以我们可以利用之前讲过的正则表达式的知识,从页面的 HTML 代码中提取新闻的标题和链接,代码如下所示。
import re
import requests
pattern = re.compile(r'<a.*?href="(.*?)".*?title="(.*?)".*?>')
resp = requests.get('https://www.sohu.com/')
if resp.status_code == 200:
all_matches = pattern.findall(resp.text)
for href, title in all_matches:
print(href)
print(title)
除了文本内容,我们也可以使用requests库通过 URL 获取二进制资源。下面的例子演示了如何获取百度 Logo 并保存到名为baidu.png的本地文件中。可以在百度的首页上右键点击百度Logo,并通过“复制图片地址”菜单项获取图片的 URL。
import requests
resp = requests.get('https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png')
with open('baidu.png', 'wb') as file:
file.write(resp.content)
说明:Response对象的content属性可以获得服务器响应的二进制数据。
requests库非常好用而且功能上也比较强大和完整,具体的内容我们在使用的过程中为大家一点点剖析。想解锁关于requests库更多的知识,可以阅读它的 官方文档。
编写爬虫代码
接下来,我们以“豆瓣电影”为例,为大家讲解如何编写爬虫代码。按照上面提供的方法,我们先使用requests获取到网页的HTML代码,然后将整个代码看成一个长字符串,这样我们就可以使用正则表达式的捕获组从字符串提取我们需要的内容。下面的代码演示了如何从 豆瓣电影获取排前250名的电影的名称。 豆瓣电影Top250的页面结构和对应代码如下图所示,可以看出,每页共展示了25部电影,如果要获取到 Top250 数据,我们共需要访问10个页面,对应的地址是 https://movie.douban.com/top250?start=xxx,这里的xxx如果为0就是第一页,如果xxx的值是100,那么我们可以访问到第五页。为了代码简单易读,我们只获取电影的标题和评分。
import random
import re
import time
import requests
for page in range(1, 11):
resp = requests.get(
url=f'https://movie.douban.com/top250?start={(page - 1) * 25}',
# 如果不设置HTTP请求头中的User-Agent,豆瓣会检测出不是浏览器而阻止我们的请求。
# 通过get函数的headers参数设置User-Agent的值,具体的值可以在浏览器的开发者工具查看到。
# 用爬虫访问大部分网站时,将爬虫伪装成来自浏览器的请求都是非常重要的一步。
headers={'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'}
)
# 通过正则表达式获取class属性为title且标签体不以&开头的span标签并用捕获组提取标签内容
pattern1 = re.compile(r'<span class="title">([^&]*?)</span>')
titles = pattern1.findall(resp.text)
# 通过正则表达式获取class属性为rating_num的span标签并用捕获组提取标签内容
pattern2 = re.compile(r'<span class="rating_num".*?>(.*?)</span>')
ranks = pattern2.findall(resp.text)
# 使用zip压缩两个列表,循环遍历所有的电影标题和评分
for title, rank in zip(titles, ranks):
print(title, rank)
# 随机休眠1-5秒,避免爬取页面过于频繁
time.sleep(random.random() * 4 + 1)
说明:通过分析豆瓣网的robots协议,我们发现豆瓣网并不拒绝百度爬虫获取它的数据,因此我们也可以将爬虫伪装成百度的爬虫,将get函数的headers参数修改为:headers={'User-Agent': 'BaiduSpider'}。
使用 IP 代理
让爬虫程序隐匿自己的身份对编写爬虫程序来说是比较重要的,很多网站对爬虫都比较反感的,因为爬虫会耗费掉它们很多的网络带宽并制造很多无效的流量。要隐匿身份通常需要使用商业 IP 代理(如蘑菇代理、芝麻代理、快代理等),让被爬取的网站无法获取爬虫程序来源的真实 IP 地址,也就无法简单的通过 IP 地址对爬虫程序进行封禁。
下面以 蘑菇代理为例,为大家讲解商业 IP 代理的使用方法。首先需要在该网站注册一个账号,注册账号后就可以 购买相应的套餐来获得商业 IP 代理。作为商业用途,建议大家购买不限量套餐,这样可以根据实际需要获取足够多的代理 IP 地址;作为学习用途,可以购买包时套餐或根据自己的需求来决定。蘑菇代理提供了两种接入代理的方式,分别是 API 私密代理和 HTTP 隧道代理,前者是通过请求蘑菇代理的 API 接口获取代理服务器地址,后者是直接使用统一的入口(蘑菇代理提供的域名)进行接入。
下面,我们以HTTP隧道代理为例,为大家讲解接入 IP 代理的方式,大家也可以直接参考蘑菇代理官网提供的代码来为爬虫设置代理。
import requests
APP_KEY = 'Wnp******************************XFx'
PROXY_HOST = 'secondtransfer.moguproxy.com:9001'
for page in range(1, 11):
resp = requests.get(
url=f'https://movie.douban.com/top250?start={(page - 1) * 25}',
# 需要在HTTP请求头设置代理的身份认证方式
headers={
'Proxy-Authorization': f'Basic {APP_KEY}',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36',
'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4'
},
# 设置代理服务器
proxies={
'http': f'http://{PROXY_HOST}',
'https': f'https://{PROXY_HOST}'
},
verify=False
)
pattern1 = re.compile(r'<span class="title">([^&]*?)</span>')
titles = pattern1.findall(resp.text)
pattern2 = re.compile(r'<span class="rating_num".*?>(.*?)</span>')
ranks = pattern2.findall(resp.text)
for title, rank in zip(titles, ranks):
print(title, rank)
说明:上面的代码需要修改APP_KEY为自己创建的订单对应的Appkey值,这个值可以在用户中心用户订单中查看到。蘑菇代理提供了免费的 API 代理和 HTTP 隧道代理试用,但是试用的代理接通率不能保证,建议大家还是直接购买一个在自己支付能力范围内的代理服务来体验。
另注:蘑菇代理目前已经停止服务了,大家可以按照上面讲解的方式使用其他商业代理即可。
用Python解析HTML页面
在前面的课程中,我们讲到了使用request三方库获取网络资源,还介绍了一些前端的基础知识。接下来,我们继续探索如何解析 HTML 代码,从页面中提取出有用的信息。之前,我们尝试过用正则表达式的捕获组操作提取页面内容,但是写出一个正确的正则表达式也是一件让人头疼的事情。为了解决这个问题,我们得先深入的了解一下 HTML 页面的结构,并在此基础上研究另外的解析页面的方法。
HTML 页面的结构
我们在浏览器中打开任意一个网站,然后通过鼠标右键菜单,选择“显示网页源代码”菜单项,就可以看到网页对应的 HTML 代码。
代码的第1行是文档类型声明,第2行的<html>标签是整个页面根标签的开始标签,最后一行是根标签的结束标签</html>。<html>标签下面有两个子标签<head>和<body>,放在<body>标签下的内容会显示在浏览器窗口中,这部分内容是网页的主体;放在<head>标签下的内容不会显示在浏览器窗口中,但是却包含了页面重要的元信息,通常称之为网页的头部。HTML 页面大致的代码结构如下所示。
<!doctype html>
<html>
<head>
<!-- 页面的元信息,如字符编码、标题、关键字、媒体查询等 -->
</head>
<body>
<!-- 页面的主体,显示在浏览器窗口中的内容 -->
</body>
</html>
标签、层叠样式表(CSS)、JavaScript 是构成 HTML 页面的三要素,其中标签用来承载页面要显示的内容,CSS 负责对页面的渲染,而 JavaScript 用来控制页面的交互式行为。要实现 HTML 页面的解析,可以使用 XPath 的语法,它原本是 XML 的一种查询语法,可以根据 HTML 标签的层次结构提取标签中的内容或标签属性;此外,也可以使用 CSS 选择器来定位页面元素,就跟用 CSS 渲染页面元素是同样的道理。
XPath 解析
XPath 是在 XML(eXtensible Markup Language)文档中查找信息的一种语法,XML 跟 HTML 类似也是一种用标签承载数据的标签语言,不同之处在于 XML 的标签是可扩展的,可以自定义的,而且 XML 对语法有更严格的要求。XPath 使用路径表达式来选取 XML 文档中的节点或者节点集,这里所说的节点包括元素、属性、文本、命名空间、处理指令、注释、根节点等。下面我们通过一个例子来说明如何使用 XPath 对页面进行解析。
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title lang="zh">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>
对于上面的 XML 文件,我们可以用如下所示的 XPath 语法获取文档中的节点。
路径表达式
结果
/bookstore
选取根元素 bookstore。注意:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!
//book
选取所有 book 子元素,而不管它们在文档中的位置。
//@lang
选取名为 lang 的所有属性。
/bookstore/book[1]
选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()]
选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1]
选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()<3]
选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
//title[@lang]
选取所有拥有名为 lang 的属性的 title 元素。
//title[@lang='eng']
选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。
/bookstore/book[price>35.00]
选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。
/bookstore/book[price>35.00]/title
选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。
XPath还支持通配符用法,如下所示。
路径表达式
结果
/bookstore/*
选取 bookstore 元素的所有子元素。
//*
选取文档中的所有元素。
//title[@*]
选取所有带有属性的 title 元素。
如果要选取多个节点,可以使用如下所示的方法。
路径表达式
结果
//book/title | //book/price
选取 book 元素的所有 title 和 price 元素。
//title | //price
选取文档中的所有 title 和 price 元素。
/bookstore/book/title | //price
选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。
说明:上面的例子来自于“菜鸟教程”网站上的 XPath 教程,有兴趣的读者可以自行阅读原文。
当然,如果不理解或不熟悉 XPath 语法,可以在浏览器的开发者工具中按照如下所示的方法查看元素的 XPath 语法
实现 XPath 解析需要三方库lxml 的支持,可以使用下面的命令安装lxml。
pip install lxml
1.
下面我们用 XPath 解析方式改写之前获取豆瓣电影 Top250的代码,如下所示。
from lxml import etree
import requests
for page in range(1, 11):
resp = requests.get(
url=f'https://movie.douban.com/top250?start={(page - 1) * 25}',
headers={'User-Agent': 'BaiduSpider'}
)
tree = etree.HTML(resp.text)
# 通过XPath语法从页面中提取电影标题
title_spans = tree.xpath('//*[@id="content"]/div/div[1]/ol/li/div/div[2]/div[1]/a/span[1]')
# 通过XPath语法从页面中提取电影评分
rank_spans = tree.xpath('//*[@id="content"]/div/div[1]/ol/li[1]/div/div[2]/div[2]/div/span[2]')
for title_span, rank_span in zip(title_spans, rank_spans):
print(title_span.text, rank_span.text)
CSS 选择器解析
对于熟悉 CSS 选择器和 JavaScript 的开发者来说,通过 CSS 选择器获取页面元素可能是更为简单的选择,因为浏览器中运行的 JavaScript 本身就可以document对象的querySelector()和querySelectorAll()方法基于 CSS 选择器获取页面元素。在 Python 中,我们可以利用三方库beautifulsoup4或pyquery来做同样的事情。Beautiful Soup 可以用来解析 HTML 和 XML 文档,修复含有未闭合标签等错误的文档,通过为待解析的页面在内存中创建一棵树结构,实现对从页面中提取数据操作的封装。可以用下面的命令来安装 Beautiful Soup。
pip install beautifulsoup4
下面是使用bs4改写的获取豆瓣电影Top250电影名称的代码。
import bs4
import requests
for page in range(1, 11):
resp = requests.get(
url=f'https://movie.douban.com/top250?start={(page - 1) * 25}',
headers={'User-Agent': 'BaiduSpider'}
)
# 创建BeautifulSoup对象
soup = bs4.BeautifulSoup(resp.text, 'lxml')
# 通过CSS选择器从页面中提取包含电影标题的span标签
title_spans = soup.select('div.info > div.hd > a > span:nth-child(1)')
# 通过CSS选择器从页面中提取包含电影评分的span标签
rank_spans = soup.select('div.info > div.bd > div > span.rating_num')
for title_span, rank_span in zip(title_spans, rank_spans):
print(title_span.text, rank_span.text)
关于 BeautifulSoup 更多的知识,可以参考它的 官方文档。
简单的总结
下面我们对三种解析方式做一个简单比较。
解析方式
对应的模块
速度
使用难度
正则表达式解析
re
快
困难
XPath 解析
lxml
快
一般
CSS 选择器解析
bs4或pyquery
不确定
简单
爬虫框架Scrapy简介
当你写了很多个爬虫程序之后,你会发现每次写爬虫程序时,都需要将页面获取、页面解析、爬虫调度、异常处理、反爬应对这些代码从头至尾实现一遍,这里面有很多工作其实都是简单乏味的重复劳动。那么,有没有什么办法可以提升我们编写爬虫代码的效率呢?答案是肯定的,那就是利用爬虫框架,而在所有的爬虫框架中,Scrapy 应该是最流行、最强大的框架。
Scrapy 概述
Scrapy 是基于 Python 的一个非常流行的网络爬虫框架,可以用来抓取 Web 站点并从页面中提取结构化的数据。
Scrapy的组件
我们先来说说 Scrapy 中的组件。
Scrapy 引擎(Engine):用来控制整个系统的数据处理流程。
调度器(Scheduler):调度器从引擎接受请求并排序列入队列,并在引擎发出请求后返还给它们。
下载器(Downloader):下载器的主要职责是抓取网页并将网页内容返还给蜘蛛(Spiders)。
蜘蛛程序(Spiders):蜘蛛是用户自定义的用来解析网页并抓取特定URL的类,每个蜘蛛都能处理一个域名或一组域名,简单的说就是用来定义特定网站的抓取和解析规则的模块。
数据管道(Item Pipeline):管道的主要责任是负责处理有蜘蛛从网页中抽取的数据条目,它的主要任务是清理、验证和存储数据。当页面被蜘蛛解析后,将被发送到数据管道,并经过几个特定的次序处理数据。每个数据管道组件都是一个 Python 类,它们获取了数据条目并执行对数据条目进行处理的方法,同时还需要确定是否需要在数据管道中继续执行下一步或是直接丢弃掉不处理。数据管道通常执行的任务有:清理 HTML 数据、验证解析到的数据(检查条目是否包含必要的字段)、检查是不是重复数据(如果重复就丢弃)、将解析到的数据存储到数据库(关系型数据库或 NoSQL 数据库)中。
中间件(Middlewares):中间件是介于引擎和其他组件之间的一个钩子框架,主要是为了提供自定义的代码来拓展 Scrapy 的功能,包括下载器中间件和蜘蛛中间件。
数据处理流程
Scrapy 的整个数据处理流程由引擎进行控制,通常的运转流程包括以下的步骤:
引擎询问蜘蛛需要处理哪个网站,并让蜘蛛将第一个需要处理的 URL 交给它。
引擎让调度器将需要处理的 URL 放在队列中。
引擎从调度那获取接下来进行爬取的页面。
调度将下一个爬取的 URL 返回给引擎,引擎将它通过下载中间件发送到下载器。
当网页被下载器下载完成以后,响应内容通过下载中间件被发送到引擎;如果下载失败了,引擎会通知调度器记录这个 URL,待会再重新下载。
引擎收到下载器的响应并将它通过蜘蛛中间件发送到蜘蛛进行处理。
蜘蛛处理响应并返回爬取到的数据条目,此外还要将需要跟进的新的 URL 发送给引擎。
引擎将抓取到的数据条目送入数据管道,把新的 URL 发送给调度器放入队列中。
上述操作中的第2步到第8步会一直重复直到调度器中没有需要请求的 URL,爬虫就停止工作。
安装和使用Scrapy
可以使用 Python 的包管理工具pip来安装 Scrapy。
pip install scrapy
在命令行中使用scrapy命令创建名为demo的项目。
scrapy startproject demo
项目的目录结构如下图所示。
demo
|____ demo
|________ spiders
|____________ __init__.py
|________ __init__.py
|________ items.py
|________ middlewares.py
|________ pipelines.py
|________ settings.py
|____ scrapy.cfg
切换到demo 目录,用下面的命令创建名为douban的蜘蛛程序。
scrapy genspider douban movie.douban.com
一个简单的例子
接下来,我们实现一个爬取豆瓣电影 Top250 电影标题、评分和金句的爬虫。
在items.py的Item类中定义字段,这些字段用来保存数据,方便后续的操作。
import scrapy
class DoubanItem(scrapy.Item):
title = scrapy.Field()
score = scrapy.Field()
motto = scrapy.Field()
修改spiders文件夹中名为douban.py 的文件,它是蜘蛛程序的核心,需要我们添加解析页面的代码。在这里,我们可以通过对Response对象的解析,获取电影的信息,代码如下所示。
import scrapy
from scrapy import Selector, Request
from scrapy.http import HtmlResponse
from demo.items import MovieItem
class DoubanSpider(scrapy.Spider):
name = 'douban'
allowed_domains = ['movie.douban.com']
start_urls = ['https://movie.douban.com/top250?start=0&filter=']
def parse(self, response: HtmlResponse):
sel = Selector(response)
movie_items = sel.css('#content > div > div.article > ol > li')
for movie_sel in movie_items:
item = MovieItem()
item['title'] = movie_sel.css('.title::text').extract_first()
item['score'] = movie_sel.css('.rating_num::text').extract_first()
item['motto'] = movie_sel.css('.inq::text').extract_first()
yield item
通过上面的代码不难看出,我们可以使用 CSS 选择器进行页面解析。当然,如果你愿意也可以使用 XPath 或正则表达式进行页面解析,对应的方法分别是xpath和re。
如果还要生成后续爬取的请求,我们可以用yield产出Request对象。Request对象有两个非常重要的属性,一个是url,它代表了要请求的地址;一个是callback,它代表了获得响应之后要执行的回调函数。我们可以将上面的代码稍作修改。
import scrapy
from scrapy import Selector, Request
from scrapy.http import HtmlResponse
from demo.items import MovieItem
class DoubanSpider(scrapy.Spider):
name = 'douban'
allowed_domains = ['movie.douban.com']
start_urls = ['https://movie.douban.com/top250?start=0&filter=']
def parse(self, response: HtmlResponse):
sel = Selector(response)
movie_items = sel.css('#content > div > div.article > ol > li')
for movie_sel in movie_items:
item = MovieItem()
item['title'] = movie_sel.css('.title::text').extract_first()
item['score'] = movie_sel.css('.rating_num::text').extract_first()
item['motto'] = movie_sel.css('.inq::text').extract_first()
yield item
hrefs = sel.css('#content > div > div.article > div.paginator > a::attr("href")')
for href in hrefs:
full_url = response.urljoin(href.extract())
yield Request(url=full_url)
到这里,我们已经可以通过下面的命令让爬虫运转起来。
scrapy crawl movie
可以在控制台看到爬取到的数据,如果想将这些数据保存到文件中,可以通过-o参数来指定文件名,Scrapy 支持我们将爬取到的数据导出成 JSON、CSV、XML 等格式。
scrapy crawl moive -o result.json
不知大家是否注意到,通过运行爬虫获得的 JSON 文件中有275条数据,那是因为首页被重复爬取了。要解决这个问题,可以对上面的代码稍作调整,不在parse方法中解析获取新页面的 URL,而是通过start_requests方法提前准备好待爬取页面的 URL,调整后的代码如下所示。
import scrapy
from scrapy import Selector, Request
from scrapy.http import HtmlResponse
from demo.items import MovieItem
class DoubanSpider(scrapy.Spider):
name = 'douban'
allowed_domains = ['movie.douban.com']
def start_requests(self):
for page in range(10):
yield Request(url=f'https://movie.douban.com/top250?start={page * 25}')
def parse(self, response: HtmlResponse):
sel = Selector(response)
movie_items = sel.css('#content > div > div.article > ol > li')
for movie_sel in movie_items:
item = MovieItem()
item['title'] = movie_sel.css('.title::text').extract_first()
item['score'] = movie_sel.css('.rating_num::text').extract_first()
item['motto'] = movie_sel.css('.inq::text').extract_first()
yield item
如果希望完成爬虫数据的持久化,可以在数据管道中处理蜘蛛程序产生的Item对象。例如,我们可以通过前面讲到的openpyxl操作 Excel 文件,将数据写入 Excel 文件中,代码如下所示。
import openpyxl
from demo.items import MovieItem
class MovieItemPipeline:
def __init__(self):
self.wb = openpyxl.Workbook()
self.sheet = self.wb.active
self.sheet.title = 'Top250'
self.sheet.append(('名称', '评分', '名言'))
def process_item(self, item: MovieItem, spider):
self.sheet.append((item['title'], item['score'], item['motto']))
return item
def close_spider(self, spider):
self.wb.save('豆瓣电影数据.xlsx')
上面的process_item和close_spider都是回调方法(钩子函数), 简单的说就是 Scrapy 框架会自动去调用的方法。当蜘蛛程序产生一个Item对象交给引擎时,引擎会将该Item对象交给数据管道,这时我们配置好的数据管道的parse_item方法就会被执行,所以我们可以在该方法中获取数据并完成数据的持久化操作。另一个方法close_spider是在爬虫结束运行前会自动执行的方法,在上面的代码中,我们在这个地方进行了保存 Excel 文件的操作,相信这段代码大家是很容易读懂的。
总而言之,数据管道可以帮助我们完成以下操作:
清理 HTML 数据,验证爬取的数据。
丢弃重复的不必要的内容。
将爬取的结果进行持久化操作。
修改settings.py文件对项目进行配置,主要需要修改以下几个配置。
# 用户浏览器
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
# 并发请求数量
CONCURRENT_REQUESTS = 4
# 下载延迟
DOWNLOAD_DELAY = 3
# 随机化下载延迟
RANDOMIZE_DOWNLOAD_DELAY = True
# 是否遵守爬虫协议
ROBOTSTXT_OBEY = True
# 配置数据管道
ITEM_PIPELINES = {
'demo.pipelines.MovieItemPipeline': 300,
}
说明:上面配置文件中的ITEM_PIPELINES选项是一个字典,可以配置多个处理数据的管道,后面的数字代表了执行的优先级,数字小的先执行。
© Copyright 2014 - 2024 柏港建站平台 ejk5.com. 渝ICP备16000791号-4