class DoubanSpider(scrapy.Spider):
name = "douban"
allowed_domains = ["movie.douban.com"]
start_urls = ["https://movie.douban.com/chart"]
def parse(self, response):
titles = response.css('#content > div > div.article > div > div > table:nth-child(2) > tbody > tr > td:nth-child(2) > div > a::text').extract_first()
stars = response.css('#content > div > div.article > div > div > table:nth-child(2) > tbody > tr > td:nth-child(2) > div > div > span.rating_nums::text').extract_first()
print(f'title: {titles}, star: {stars}')
titles = response.xpath('//tbody/tr/td[2]/div/a/text()').extract_first()
stars = response.xpath('//tbody/tr/td[2]/div/div/span[2]/text()').extract_first()
print(f'title: {titles}, star: {stars}')
上面是使用 scrapy 框架爬取豆瓣电影的一个代码片段,从中可以知道我使用了 css 和 xpath 两种数据提取方法去提取元素,但这两种元素都有一个特点那就是:他们都是我从浏览器上直接右键复制得到的。起初认为没毛病,运行后才发现:
两者都没有起到作用,于是我再次返回浏览器使用XPath插件验证, 发现如下:
确实获取到了, 一阵莫名其妙,于是我不用浏览器复制得到的结果,直接自己去模拟推导一下xpath路径,结果如下:
将xpath粘贴到代码中:
def parse(self, response):
titles = response.xpath('//div[@class="pl2"]/a/text()').getall()
stars = response.xpath('//span[@class="rating_nums"]/text()').getall()
titles = [title.strip()[:-1].strip() for title in titles if title.strip()]
#print(f'titles.len: {len(titles)}, stars.len: {len(stars)}')
for title , star in zip(titles, stars):
print(f'title: {title}, star: {star}')
运行得到如图,成功。。。
经过这次教训,直接就让我放弃了靠浏览器吃饭的想法,还是得自身实力硬,浏览器只能起到辅助作用。
下面解释原因:
经过打印抓取到的 HTML 源代码可知: print(response.text)
源码的结构和实际上F12得到的结构是有出入的,部分元素可能是通过 JavaScript 动态加载的,
标签:解决办法,None,title,text,scrapy,titles,stars,div,response From: https://blog.csdn.net/m0_74091159/article/details/144741618
而//tbody/tr/td[2]/div/a/text()
是一个更具体的 XPath,如果页面结构稍有变化,它可能就会失效,而//div[@class="pl2"]/a/text()
更通用,容错性更强。