打开我们之前建立的爬虫工程,在spider目录下建立爬虫文件qidian_spider.py
导入需要用到的库
from scrapy import Request
from scrapy.spiders import Spider
创建一个继承自 Spider的爬虫类,其中包含爬虫名称、目标网页、解析方法
class HotSaleSpider(Spider):
name = "hot" #爬虫名称
start_urls = ["https://www.qidian.com/rank/hotsales?style=1"]#目标网站地址
def parse(self, response):#用于数据解析
pass
注意到parse方法的参数是response,这是因为我们使用爬虫框架会自动帮我们得到网页的响应,不需要我们另外编写代码向网页发起request请求,在scrapy内部已经发起请求并直接返回响应了。
下图是scrapy框架的结构,我们需要做的就是完成spider的部分:得到网页响应后进行提取信息。在爬虫内部完成了1-6的工作。
所以我们重点编写parse方法。基于我们之前的网页分析,这里使用xpath方法提取信息。
首先我们定位到class="book-mid-info"
,每本小说的信息都保存在这个"book-mid-info"类之下。
list_selector = response.xpath("//div[@class='book-mid-info']")
然后遍历每一本小说,获取各项信息,定位的方法同样是查看信息所在的标签。小说名称“诡秘之主”保存在"book-mid-info"类中的h4标签下的a标签,小说作者“爱潜水的乌贼”保存在"book-mid-info"类中的p标签下的a标签。
for one_selector in list_selector:
# 获取小说信息
name = one_selector.xpath("h4/a/text()").extract()[0] #提取当前定位下的文字
author = one_selector.xpath("p[1]/a[1]/text()").extract()[0]
type = one_selector.xpath("p[1]/a[2]/text()").extract()[0]
form = one_selector.xpath("p[1]/span/text()").extract()[0]
最后定义一个字典保存每本小说的各项信息并且通过生成器返回:
# 保存小说信息为字典
hot_dict = {
"name":name,
"author":author,
"type":type,
"form":form
}
yield hot_dict # 生成器返回每一本小说的信息
关于yield关键字的含义可以参看:Python关键字:yield生成器
完整代码:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#@Time : 2020/2/20 11:45
#@Author: bz
#@File : qidian_spider.py
from scrapy import Request
from scrapy.spiders import Spider
class HotSaleSpider(Spider):
name = "hot" #爬虫名称
start_urls = ["https://www.qidian.com/rank/hotsales?style=1"]#目标网站地址
def parse(self, response):#用于数据解析
#使用xpath定位
list_selector = response.xpath("//div[@class='book-mid-info']")
for one_selector in list_selector:
# 获取小说信息
name = one_selector.xpath("h4/a/text()").extract()[0] #提取当前定位下的文字
author = one_selector.xpath("p[1]/a[1]/text()").extract()[0]
type = one_selector.xpath("p[1]/a[2]/text()").extract()[0]
form = one_selector.xpath("p[1]/span/text()").extract()[0]
# 保存小说信息为字典
hot_dict = {
"name":name,
"author":author,
"type":type,
"form":form
}
yield hot_dict # 生成器返回每一本小说的信息
首先,可能是因为Scrapy中的响应对象不同于Python中的request库,需要使用Selector类来解析响应数据。可以使用以下代码将响应数据加载到Selector对象中:
from scrapy.selector import Selector
selector = Selector(text=response.text)
如果还是不能获取到数据,可以检查xpath表达式是否正确。在Scrapy中使用xpath语法时,需要注意"."和"/"的使用,具体见参考资料中的段落1。
如果还是不能解决问题,可以尝试使用Chrome浏览器的开发者工具查看目标数据在网页源代码中的位置,从而确定正确的xpath表达式。
最后,可以检查是否需要先调用extract()方法将Selector对象转化为字符串类型才能获取数据。如:
title = selector.xpath('//title/text()').extract_first()