基于scrapy框架的爬虫基本步骤

231 阅读5分钟

本文以网站 代码的边城 为例 1.安装scrapy框架

详细教程可以查看本站文章 点击跳转

2.新建scrapy项目

生成一个爬虫文件。在指定的目录打开cmd.exe文件,输入代码

scrapy startproject mxp7 
cd mxp7 
scrapy genspider sp mxp7.com

然后通过Pycharm打开我们新建的项目,可以发现所有文件都已经新建好了,我们只需要在文件里修改好代码,就可以在命令行中输入命令爬取数据了。

此图像的alt属性为空;文件名为1617605536061.png

3.提取数据

先点击开一个网页,查看博客的基本框架,然后我们在sp.py,我们的爬虫文件里面新建item字典,通过xpath提取出博客的各项内容。

**注:在这里强调一个与xpath有关的坑。**笔者起初获取网页标签内容时,喜欢在浏览器调试目录下复制xpath

此图像的alt属性为空;文件名为1617612511922.png

比如像上图一样复制title的xpath,获得的xpath内容如下,他会按照标签的顺序提取xpath

/html/body/div[2]/div[1]/section[1]/main/article/header/h1

然而这种情况只针对于静态网页,因为动态网页中某些信息是通过代码动态加载出来的,我们复制的xpath就是动态加载后的目录,但在爬取数据的时,爬虫是不会加载动态界面的,它只爬取response内容下的原始代码。如果想让爬虫通过标签顺序获取网页内容,那必须对照着response下的代码,一般来说计算起来相当麻烦。

如何打开网页的Response

打开目标网页,点击F12进入浏览器调试,选择Network后,按F5刷新,界面下方就会出现该网页调用的文件,选择当前网址的同名文件,再在右边点击顶部菜单"Response",我们就可以查看response的内容了

此图像的alt属性为空;文件名为1617613160824-1024x428.png

话说回来,在浏览器调试界面我们还可以通过检索id获取xpath

此图像的alt属性为空;文件名为1617613605957.png

获取内容如下:

//\*\[@id="post-331"\]/header/h1

然而,我们会发现id与网站分页的编号相同,这意味着每张网页此目录下的标签,它的id都是不同的,所以就不能通过id抽象出所有网页的xpath,因此笔者在这里更推荐大家通过css的xpath提取路径。我们写好xpath内容之后,获得的sp.py的源代码如下所示:

import scrapy


class SpSpider(scrapy.Spider):
    name = 'sp'
    allowed_domains = ['mxp7.com']
    start_urls = ['http://mxp7.com']

    def parse(self, response):
        href = response.xpath("//h2[@class = 'entry-title'][1]//a/@href").extract_first()
        print(href)
        yield scrapy.Request(href, callback=self.parse1)

    def parse1(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()
        yield item

在这里我们就把数据抛给了pipelines,然后我们就可以在pipelines里面处理数据,笔者选择在这里将传送过来的数据输出到命令行

# pipelines.py源码
class Mxp7Pipeline:
    def process_item(self, item, spider):
        return item

pipelines数据处理完毕后,我们还需要在setting.py里面打开pipelines

此图像的alt属性为空;文件名为1617610290687.png

找到这段代码将其取消注释,这段代码调用了我们pipelines里面的函数,后面的300指的是该函数的权重,这个权重会在并行pipelines里面决定数据处理的优先级。

将这里处理完毕后,我们在 D:\Project\Spider\mxp7>路径下可以进行我们的抓取了,输入命令行

此图像的alt属性为空;文件名为1617610767048.png

然后会发现我们抓取的数据藏在了一大堆日志文件里面,为了视觉上的感受,我们可以在setting.py里面添加一段代码,使得输出日志的等级为ERROR

然后重新在cmd里输入抓取命令

此图像的alt属性为空;文件名为1617610980100.png

我们就可以成功抓取该页面的内容了

如果我们要获取博客上发布的所有内容,那我们就还需要对sp.py进行修改,在parse函数里面添加获取下一页的代码,可以先在浏览器上打开该网页,查看下一页网页的格式,可以发现下一页已经是完整格式的链接了

此图像的alt属性为空;文件名为1617611310624.png

那么我们直接在抛出的scrapy.Request参数里面使用我们获取的网页即可

pre\_url = response.xpath("//div\[@class = 'nav-previous'\]//a/@href").extract\_first() 
if pre\_url: 
    yield scrapy.Request(pre\_url, callback=self.parse1)//调用自身

但在某些网站获得的网址并不是一个完整的网址(笔者的网站的反爬机制相当的弱)

此图像的alt属性为空;文件名为1617611565470.png

就需要在提取的网址前在加入该网页的头部地址,这里相信各位自己可以操作,暂不赘述。修改完后我们还需要在setting.py里修改USER_AGENT的值,在修改之前还需要获取网页的USER_AGENT的值。

**注:**USER_AGENT是爬虫与网站反爬虫机制交锋的地方,双方会针对这一部分做出千变万化的措施来相互对抗。笔者此步骤只适用于最简单的反爬虫机制。实际上笔者的网站目前并没有任何的反爬虫机制,即使是不进行这一步,我们也可以正常地爬取完所有的文章内容。

打开Network界面后,在右下方点击顶部菜单"Headers",滑到底部就可以获取user-agent的值了

此图像的alt属性为空;文件名为1617612276190-1024x600.png

然后我们在setting找到被注释的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界面抓取数据

此图像的alt属性为空;文件名为1617614951602.png

成功抓取网站所有文章的内容

4.保存文件

如果想保存文件,那只需要在命令行里输入如下代码:

scrapy crawl sp -o mxp7.csv

在当前目录会新建一个mxp7.csv文件

此图像的alt属性为空;文件名为1617615157028.png

打开发现是乱码,我们可以通过记事本打开,另存为此格式

此图像的alt属性为空;文件名为1617615510892.png

重新打开后就可以获得正常的文件了

此图像的alt属性为空;文件名为1617615698327.png