scrapy分页抓取网页(本文以爬取网站:为例1.安装scrapy框架详细教程 )
优采云 发布时间: 2021-12-26 08:16scrapy分页抓取网页(本文以爬取网站:为例1.安装scrapy框架详细教程
)
本文以爬取网站为例
1.安装scrapy框架
点击这里跳转到详细教程
2.新的scrapy项目
生成爬虫文件。打开指定目录下的cmd.exe文件,输入代码
scrapy startproject mxp7
cd mxp7
scrapy genspider sp mxp7.com
然后通过Pycharm打开我们新创建的项目,可以发现所有的文件都已经创建好了,我们只需要修改文件中的代码,然后就可以在命令行爬取数据了。
3.提取数据
首先点击打开一个网页,查看博客的基本框架,然后我们在我们的爬虫文件sp.py中创建一个条目字典,通过xpath提取博客的内容。
注:这里强调一个xpath相关的坑。第一次拿到网页标签内容的时候,喜欢把xpath复制到浏览器调试目录下
比如复制上图title的xpath,得到的xpath内容如下,他会按照tags的顺序提取xpath
/html/body/div[2]/div[1]/section[1]/main/article/header/h1
但是这种情况只针对静态网页,因为动态网页中的一些信息是通过代码动态加载的。我们复制的xpath是动态加载后的目录,但是爬取数据的时候,爬虫不会动态加载接口,只会爬取响应内容下的原代码。如果想让爬虫通过标签序列获取网页的内容,就必须与响应下的代码进行比较。一般来说,计算起来相当麻烦。
如何打开网页的响应
打开目标网页,点击F12进入浏览器调试,选择Network后按F5刷新,界面下方会出现网页调用的文件,选择与当前URL同名的文件,然后点击右侧的顶部菜单“响应”,我们可以查看响应的内容
话虽如此,在浏览器调试界面中,我们也可以通过检索id来获取xpath
内容如下:
//*[@id="post-331"]/header/h1
会发现id和网页的编号是一样的,也就是说每个网页的tag的id都不一样。我们不能通过id提取所有网页的xpath路径,所以这里作者推荐大家通过css path的xpath提取。我们写完xpath的内容后,得到的sp.py的源码如下:
# sp.py源码
import scrapy
class SpSpider(scrapy.Spider):
name = 'sp'
allowed_domains = ['mxp7.com']
start_urls = ['http://mxp7.com/331/']
def parse(self, response):
item = {}
item["date"] = response.xpath("//span[@class ='meta-date']//time/text()").extract_first()
item["category"] = response.xpath("//span[@class = 'meta-category']//a/text()").extract_first()
item["title"] = response.xpath("//h1[@class = 'entry-title']/text()").extract_first()
item["author"] = response.xpath("//span[@class = 'meta-author']//a/text()").extract_first()
contain_path = response.xpath("//div[@class = 'entry-content clearfix']")
item["contain"] = contain_path.xpath("string(.)").extract_first()
print(item)
yield item
这里我们把数据扔到管道中,然后我们就可以对管道中的数据进行处理了。笔者这里选择将传输的数据输出到命令行。
# pipelines.py源码
class Mxp7Pipeline:
def process_item(self, item, spider):
print(item)
return item
处理好pipelines数据后,我们还需要在setting.py中打开pipelines
找到此代码并取消注释。此代码调用我们管道中的函数。下面的300指的是函数的权重。这个权重将决定并行管道中数据处理的优先级。
处理完这个,我们就可以在路径D:\Project\Spider\mxp7>下开始我们的爬行,进入命令行
scrapy crawl sp
然后你会发现我们抓取的数据隐藏在很多日志文件中。为了视觉体验,我们可以在setting.py中添加一段代码,使输出的日志级别为ERROR
LOG_LEVEL = "WARNING"
然后在cmd中重新输入grab命令
我们可以成功抓取页面内容
如果我们想要获取博客上发布的所有内容,那么还需要修改sp.py,在parse函数中添加获取下一页的代码,可以先在浏览器上打开网页,查看下一页page 格式,可以发现下一页已经是完整格式的链接了
然后我们就可以直接使用我们在抛出的scrapy.Request参数中获取的网页
pre_url = response.xpath("//div[@class = 'nav-previous']//a/@href").extract_first()
if pre_url:
yield scrapy.Request(pre_url, callback=self.parse)//调用自身
但是在某些网站上获取到的网址并不是一个完整的网址(作者网站的反爬虫机制比较弱)
需要在提取的URL前加上网页的头地址。我相信你自己可以做到这一点,所以我暂时不再赘述。修改后,我们还需要修改setting.py中USER_AGENT的值。在修改之前,我们还需要获取网页的 USER_AGENT 的值。
注意:USER_AGENT是网站的爬虫和反爬虫机制发生冲突的地方,双方会采取千变万化的措施来对抗这部分。作者的这一步只适用于最简单的反爬虫机制。事实上,作者的网站目前没有任何反爬虫机制。即使不执行这一步,我们也可以正常抓取所有文章内容。
打开Network界面后,点击顶部菜单右下角的“Headers”,滑动到底部获取user-agent的值
然后我们在设置中找到注释的USER_AGENT代码,修改它的值为这里复制的值
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36'
处理完之后我们就可以在cmd界面再次抓取数据了
scrapy crawl sp
成功抓取网站所有文章内容
4.保存文件
如果要保存文件,只需要在命令行中输入以下代码即可:
scrapy crawl sp -o mxp7.csv
将在当前目录中创建一个新的 mxp7.csv 文件
打开后发现乱码,我们可以通过记事本打开,保存为这种格式
重新打开后就可以得到正常的文件了