首先声明:想直接看问题解决方法,可以直接拖到文章最后。
最近学习scrapy入门,按照标均流程:写一个Spider, Item, PiplineItem。但是当我写Spider,解析列表每条数据时,打印数据都一样,你敢信?
场景复现
首先明白我们的功能干啥:爬取cnblogs的首页(第一页)的列表数据。
那我们怎么干?
写三个类:
- scrapy.Spider 子类 – 配置博客地址,解析数据,详情数据可以生成Request对象,继续请求。
- scrapy.Item 子类 – 每条博文的元数据:头像,标题,简介。
- CnBlogsJsonPipeline – 在piplines.py中实现,处理Spider解析好的数据。
问题发生点
执行scrapy爬虫实现Spider的parse方法时:
解析列表的每一项,解析数据出错了,且看代码:。
class CnBlogsSpider(scrapy.Spider):
name = 'cnblogs'
allowed_domains = ["cnblogs.com"]
start_urls = [
"https://www.cnblogs.com/#p1"
]
def parse(self, response):
items = response.xpath("//div[@id='post_list']/article[@class='post-item']")
print(items)
for item in items:
new_item = CnBlogsItem()
new_item["icon"]=item.xpath("//p[@class='post-item-summary']/a/img/@src").extract_first(),
new_item["title"]=item.xpath("//a[@class='post-item-title']/text()").extract_first(),
new_item["summary"]=item.xpath("//p[@class='post-item-summary']/text()").extract_first()
yield new_item
// 输出log
2021-04-02 00:54:30 [scrapy.core.scraper] DEBUG: Scraped from <200 https://www.cnblogs.com/>
{'icon': ('https://pic.cnblogs.com/face/17148/20190706090141.png',),
'summary': '\n ',
'title': ('Vue组件(35)动态组件 component 的 is 到底可以是啥?',)}
2021-04-02 00:54:30 [scrapy.core.scraper] DEBUG: Scraped from <200 https://www.cnblogs.com/>
{'icon': ('https://pic.cnblogs.com/face/17148/20190706090141.png',),
'summary': '\n ',
'title': ('Vue组件(35)动态组件 component 的 is 到底可以是啥?',)}
{'icon': ('https://pic.cnblogs.com/face/1772871/20190819144800.png',),
'summary': '\n ',
'title': ('集群通信:从心跳说起 ',)}
看看,打印的 icon
, title
字段全是一样!!!
原因:xpath表达式如果不加.
, 那么查找数据从文档开头找起。
解决办法
正确做法是:
每个xpath开头加个英文句号’.'
new_item["icon"]=item.xpath(".//p[@class='post-item-summary']/a/img/@src").extract_first(),
new_item["title"]=item.xpath(".//a[@class='post-item-title']/text()").extract_first(),
new_item["summary"]=item.xpath(".//p[@class='post-item-summary']/text()").extract_first()
人生本来一场戏,我们却得发脾气。。。
淡定,淡定,做人呢,最重要的是开心啦。