最近跟着崔老板的视频学到了很多东西,感谢崔庆才,感谢B站,但觉得崔在scrapy这部分讲的比较快,我承认是我菜,所以我先跟着其他人学一下scrapy,回头再跟着崔的视频再过一遍。
今天要爬取的是糗事百科上的段子,网页分析这块儿我就不说了,比较简单,如果有幸被那位朋友拜读到这,祝这位朋友:三冬暖,春不寒,天黑有灯,下雨有伞:
我先展现一下我整个项目的目录吧:
-
如何在程序中启动爬虫
很简单在项目的目录下,新建一个python文件,输入几条命令,执行这个python文件,就可以带动整个爬虫项目的运行,避免一次次在命令行中执行的痛苦:
图中所示的这个文件就是我所配置的运行文件,若要运行爬虫,直接run这个start文件即可。
-
配置settings文件
这个有几个常规操作,下面我列举一下:
- 第一个False是不遵守,robot协定,具体原因自己体会
-
LOG_LEVEL是因为在运行爬虫时会有好多日志信息,我就只允许警告级别的信息出现,其他信息屏蔽了
这个是请求头,我们加个user-agent进去伪装一下
这个是管道的配置,因为我们要在pipelines.py中执行存储的操作,必须在settings文件中开启,截图中我也写了,value的数字越小代表优先级越高
这个东西是下载延迟,做人有点良知,爬东西的时候不要搞坏人家服务器
-
items.py的配置:
items.py里的东西就类似于一种数据格式,数据类型:
-
qsbk_spider.py配置:
这个东西主要就是分析网页之类的,我们先看看单个页面如何抓取吧:
具体的我瞎分析一下:
是不是这个大的div包含了很多小的div,而这些小的div正是我们要抓取的目标对象:
这段简单的代码就是为了获取那些一个个小的div
我们找这个作者的名字应该很容易吧。因为这个xpath是截取的片段,我们要要在xpath语法前加个点,代表从当前目录开始查找,然后我么导入ITEM就可以直接使用我们在items.py上配置好的数据类型,直接 在yield扔出去即可。
-
pipelines的配置
这个配置一共有三种方法,后两种比较推荐:
-
方法一:
这段代码是打开文件
因为json.dumps 序列化时对中文默认使用的ascii编码.想输出真正的中文需要指定ensure_ascii=False
-
方法二:
我们看一下输出:
sonItemExporter是以bytes字节写入的,故打开的方式是wb,同理bytes也没啥编码。
使用JsonItemExporter类,就是每次都把数据添加到内存中,最后再统一写磁盘
好处:存储的数据是一个满足Json规则的数据
坏处:如果数据量过大,这样就比较消耗内存
-
方法三:
相比较两者,这种写法比较简单
我们看一下输出:
JsonLinesExporter类就是每次调用export_item的时候,就讲这个item存储到硬盘中。
好处:每次处理数据时就直接存储到硬盘中,不消耗内存,且数据存储方式较为安全
坏处:每一个字典是一行,整个文件不是满足Json格式的文件
-
多页面抓取
下面给出qsbk_spider.py的完整代码:
# -*- coding: utf-8 -*-
import scrapy
from qsbk.items import QsbkItem
class QsbkSpiderSpider(scrapy.Spider):
name = 'qsbk_spider'
allowed_domains = ['qiushibaike.com']
start_urls = ['https://www.qiushibaike.com/text/page/1/']
def parse(self, response):
duanzidivs = response.xpath('//div[@id="content-left"]/div')
for duanzidiv in duanzidivs:
author = duanzidiv.xpath('.//h2/text()').get().strip()
#“.”在当前节点下选取
content = duanzidiv.xpath('.//div[@class="content"]/span/text()').getall()
content = ''.join(content).strip()
item = QsbkItem(author=author,content=content)
yield item
base_domain = 'https://www.qiushibaike.com'
next_url =response.xpath('//ul[@class="pagination"]/'
'li[last()]/a/@href').extract_first()
if next_url:
yield scrapy.Request(base_domain+next_url,callback=self.parse)
下面是爬取的数据:
对比网页无误
网友评论