scrapy分页抓取网页(scrapy爬虫框架的熟悉(一)——scrapy需爬取框架)
优采云 发布时间: 2021-10-23 07:09scrapy分页抓取网页(scrapy爬虫框架的熟悉(一)——scrapy需爬取框架)
熟悉scrapy爬虫框架
最近在学习scrapy爬虫框架,通过爬取Sunshine平台的内容可以进一步了解和熟悉这个框架。为了以后快速回顾一下这个爬虫框架,在此做个记录。
首先,明确抓取目标。
这是要爬取的平台,爬取的数据有标题和日期
不仅如此,我们还需要抓取详细的内容。我们随机点击一个链接,我们知道需要抓取详细的内容,如下图所示。

就我个人而言,一开始我倾向于在 xpath 方法中爬行。毕竟这个方法对我比较友好,所以我开始比较元素和网络的内容是否可以一一对应。
对比上面两张图,发现两列的内容差不多,都有表格,对应的tr/td内容也比较规整,所以初步判断可以用xpath的方法
但是,在使用 xpath 方法时要特别注意这个 tbody 字符串。它存在于元素但不存在于网络中(如下图所示)
这点在写程序时要特别注意
最后,开始创建scrapy项目并生成爬虫
创建步骤不再一一赘述。
创建后如下图所示:
下面我们直接开始编写主程序部分:
先爬取基本信息
from yangguang.items import YangguangItem
class YgSpider(scrapy.Spider):
name = 'yg'
allowed_domains = ['sun0769.com']
start_urls = ['http://wz.sun0769.com/index.php/question/report?page=']
def parse(self, response):
li_list = response.xpath("//div[@class='greyframe']/table[2]//tr")[1:]
for li in li_list:
item = YangguangItem()
item["link"] = li.xpath("./td[2]/a[2]/@href").extract_first() # 爬取进入详情页面的链接
item["title"] = li.xpath("./td[2]/a[2]/@title").extract_first() # 爬取主题
item["date"] = li.xpath("./td[5]/text()").extract_first() # 爬取日期
yield item
分析:
因为是xpath方式,首页url链接可以直接是url名:
xpath节点的内容需要通过XPath Helper插件尝试后输入到代码中。我不确定,有没有人可以指点一下?)
class YangguangItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
link = scrapy.Field()
title = scrapy.Field()
date = scrapy.Field()
detail_content = scrapy.Field()
分析:
这里的代码是echo上一个类的调用
item = YangguangItem()
class YangguangPipeline(object):
def process_item(self, item, spider):
print(item)
return item
LOG_LEVEL = "WARNING"
ITEM_PIPELINES = {
'yangguang.pipelines.YangguangPipeline': 300,
}
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
添加第一个内容可以使输出内容更加简洁,只输出警告级别以上的日志内容
第二个内容作为注释出现在文件本身中,我们可以清除它的注释
第三个内容:加上模拟浏览器行为所需的用户代理
这样我们就初步生成了一个可用的爬虫,我们运行一下看看结果
爬取结果中有日期、链接和主题。看来这个新生的爬行者还是比较健康的。
接下来我们必须种植它
爬取链接中的详细内容
前面说过,阳光平台的详细内容才是我们真正需要的,详细内容是通过链接进一步提取出来的,所以我们需要对程序进行进一步的扩展。
class YgSpider(scrapy.Spider):
name = 'yg'
allowed_domains = ['sun0769.com']
start_urls = ['http://wz.sun0769.com/index.php/question/report?page=']
def parse(self, response):
li_list = response.xpath("//div[@class='greyframe']/table[2]//tr")[1:]
for li in li_list:
item = YangguangItem()
item["link"] = li.xpath("./td[2]/a[2]/@href").extract_first()
item["title"] = li.xpath("./td[2]/a[2]/@title").extract_first()
item["date"] = li.xpath("./td[5]/text()").extract_first()
# yield item
yield scrapy.Request(
item["link"],
callback=self.parse_detail,
meta={"item": item}
)
def parse_detail(self, response): # 详情页面处理
item = response.meta["item"]
item["detail_content"] = response.xpath("//div[@class='wzy1']//tr[1]/td[@class='txt16_3']//text()").extract() # 输出详情投诉内容
yield item
将之前获取到的link链接合并到*敏*感*词*中,定义另一种方法来处理详情页。
这里主要是添加一个内容提取detail_content
我们启动爬虫后,发现内容已经展开,增加了detail_content的内容,但是内容中含有其他杂质。这时候我们就可以使用正则表达式来提取我们真正需要的内容了。
import re
class YangguangPipeline(object):
def process_item(self, item, spider):
item["detail_content"] = self.process_content(item["detail_content"])
print(item)
return item
def process_content(self, content):
"""对详情内容进行(正则)处理"""
content = [re.sub("\xa0|\s", "", i) for i in content] # 将指定字符替换为空字符
content = [i for i in content if len(i) > 0] # 去除空字符
return content
再次启动爬虫
至此,我们发现detail_content的内容变得简洁明了,不再有其他不相关的字符串干扰我们的视觉。
至此,我们的爬虫已经能够爬取一整页需要的信息了。然而,我们的爬行动物可以进一步生长,可以捕捉更多信息,而不仅仅是一页猎物。
接下来我们继续扩展爬虫来爬取多页内容。
def parse(self, response):
li_list = response.xpath("//div[@class='greyframe']/table[2]//tr")[1:]
for li in li_list:
item = YangguangItem()
item["link"] = li.xpath("./td[2]/a[2]/@href").extract_first()
item["title"] = li.xpath("./td[2]/a[2]/@title").extract_first()
item["date"] = li.xpath("./td[5]/text()").extract_first()
# yield item
yield scrapy.Request(
item["link"],
callback=self.parse_detail,
meta={"item": item}
)
# 处理下一页
next_url = response.xpath("//a[text()='>']/@href").extract_first()
print("*" * 50)
print(next_url)
if next_url is not None:
yield scrapy.Request(
next_url,
callback=self.parse
)
最后启动爬虫,效果如下
最后,我们完成了整个爬虫,但是这个爬虫不是太健康。毕竟我们没有考虑处理所谓的反爬虫机制的策略。这个爬虫可能对服务器不太友好,毕竟会增加对方服务器的压力。当然,我们的小爬虫还没有到其他人可以使用爬虫机制的地步。毕竟,它真的很小。. .
总结:
其实仔细想想,这整个爬虫的生成过程很简单,描述也只是一点点泼,因为它只说怎么做,不说为什么要做,也就是所谓知其然,不知其所以然。
比如下面的代码中,为什么后面添加了extract_first()方法?
item["link"] = li.xpath("./td[2]/a[2]/@href").extract_first()
再举个例子,下面代码的原理机制
yield scrapy.Request(
item["link"],
callback=self.parse_detail,
meta={"item": item}
)
以后需要慢慢补充。毕竟,要成为专家,您必须知道正在发生的事情以及原因。
为了记录我的学习过程,我做了我的第一个原创博客。请不要不喜欢。