本文以爬取网站 代码的边城 为例
1.安装scrapy框架
详细教程可以查看本站文章 点击跳转
2.新建scrapy项目
生成一个爬虫文件。在指定的目录打开cmd.exe文件,输入代码
scrapy startproject mxp7
cd mxp7
scrapy genspider sp mxp7.com
然后通过Pycharm打开我们新建的项目,可以发现所有文件都已经新建好了,我们只需要在文件里修改好代码,就可以在命令行中输入命令爬取数据了。
3.提取数据
先点击开一个网页,查看博客的基本框架,然后我们在sp.py,我们的爬虫文件里面新建item字典,通过xpath提取出博客的各项内容。
注:在这里强调一个与xpath有关的坑。笔者起初获取网页标签内容时,喜欢在浏览器调试目录下复制xpath
比如像上图一样复制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的内容了
话说回来,在浏览器调试界面我们还可以通过检索id获取xpath
获取内容如下:
//\*\[@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
找到这段代码将其取消注释,这段代码调用了我们pipelines里面的函数,后面的300指的是该函数的权重,这个权重会在并行pipelines里面决定数据处理的优先级。
将这里处理完毕后,我们在 D:\Project\Spider\mxp7>路径下可以进行我们的抓取了,输入命令行
然后会发现我们抓取的数据藏在了一大堆日志文件里面,为了视觉上的感受,我们可以在setting.py里面添加一段代码,使得输出日志的等级为ERROR
然后重新在cmd里输入抓取命令
我们就可以成功抓取该页面的内容了
如果我们要获取博客上发布的所有内容,那我们就还需要对sp.py进行修改,在parse函数里面添加获取下一页的代码,可以先在浏览器上打开该网页,查看下一页网页的格式,可以发现下一页已经是完整格式的链接了
那么我们直接在抛出的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)//调用自身
但在某些网站获得的网址并不是一个完整的网址(笔者的网站的反爬机制相当的弱)
就需要在提取的网址前在加入该网页的头部地址,这里相信各位自己可以操作,暂不赘述。修改完后我们还需要在setting.py里修改USER_AGENT的值,在修改之前还需要获取网页的USER_AGENT的值。
注:USER_AGENT是爬虫与网站反爬虫机制交锋的地方,双方会针对这一部分做出千变万化的措施来相互对抗。笔者此步骤只适用于最简单的反爬虫机制。实际上笔者的网站目前并没有任何的反爬虫机制,即使是不进行这一步,我们也可以正常地爬取完所有的文章内容。
打开Network界面后,在右下方点击顶部菜单"Headers",滑到底部就可以获取user-agent的值了
然后我们在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界面抓取数据
成功抓取网站所有文章的内容
4.保存文件
如果想保存文件,那只需要在命令行里输入如下代码:
scrapy crawl sp -o mxp7.csv
在当前目录会新建一个mxp7.csv文件
打开发现是乱码,我们可以通过记事本打开,另存为此格式
重新打开后就可以获得正常的文件了
原文:https://www.cnblogs.com/mxp7/p/14626997.html