什么是正确的Scrapy XPath 错误放置的元素 标签?

问题描述 投票:0回答:2

我正在设置我的第一个Scrapy Spider,我在使用xpath提取某些元素时遇到了一些困难。

我的目标是http://www.cbooo.cn/m/641515(类似于Box Office Mojo的中文网站)。我可以毫无问题地提取电影阿龙浴血记的中文名称,但我无法弄清楚如何获取它下面的信息。我相信这是因为HTML不是标准的,正如here所讨论的那样。标题下面嵌套了几个段落元素。

我在上面的链接中尝试了解决方案,并且here也无济于事。

def parse(self, response):
    chinesetitle = response.xpath('//*[@id="top"]/div[3]/div[2]/div/div[1]/div[2]/div[1]/h2/text()').extract()
    englishtitle = response.xpath('//*[@id="top"]/div[3]/div[2]/div/div[1]/div[2]/div[1]/h2/p').extract()
    chinesereleasedate = response.xpath('//*[@id="top"]/div[3]/div[2]/div/div[1]/div[2]/div[1]/p[4]').extract()
    productionregions = response.xpath('//*[@id="top"]/div[3]/div[2]/div/div[1]/div[2]/div[1]/p[6]').extract()
    chineseboxoffice = response.xpath('//*[@id="top"]/div[3]/div[2]/div/div[1]/div[2]/div[1]/p[1]/span/text()[2]').extract()
    yield {
        'chinesetitle': chinesetitle,
        'englishtitle': englishtitle,
        'chinesereleasedate': chinesereleasedate,
        'productionregions': productionregions,
        'chineseboxoffice': chineseboxoffice
        }

当我在Scrapy shell中运行蜘蛛时,蜘蛛会按预期找到中文标题。但是,其余项目会在页面上返回[]或奇怪的混合文本。

有什么建议?这是我的第一个不成熟的编程项目,所以我感谢你对我的无知和你的帮助的耐心。谢谢!

编辑

尝试在评论中实现文本清理方法。评论中的示例有效,但当我尝试重新实现它时,我得到了一个“属性错误:'列表'对象没有属性'拆分'”(请参阅​​中国票房,原产国和下面的类型示例)

def parse(self, response):
        chinesetitle = response.css('.cont h2::text').extract_first()
        englishtitle = response.css('.cont h2 + p::text').extract_first()
        chinaboxoffice = response.xpath('//span[@class="m-span"]/text()[2]').extract_first()        
        chinaboxoffice = chinaboxoffice.split('万')[0]
        chinareleasedate = response.xpath('//div[@class="ziliaofr"]/div/p[contains(text(),"上映时间")]/text()').extract_first()
        chinareleasedate = chinareleasedate.split(':')[1].split('(')[0]
        countryoforigin = response.xpath('//div[@class="ziliaofr"]/div/p')[6].xpath('text()').extract_first()
        countryoforigin = countryoforigin.split(':')[1]
        genre = response.xpath('//div[@class="ziliaofr"]/div/p[contains(text(),"类型")]/text()').extract_first()
        genre = genre.split(':')[1]
        director = response.xpath('//*[@id="tabcont1"]/dl/dd[1]/p/a/text()').extract()
python html xpath web-scraping scrapy
2个回答
2
投票

以下是一些示例,您可以从中推断出最后一个示例。请记住始终使用class或id属性来标识html元素。 /div[3]/div[2]/div/div[1]/..不是一个好习惯。

chinesetitle = response.xpath('//div[@class="ziliaofr"]/div/h2/text()').extract_first()
englishtitle = response.xpath('//div[@class="ziliaofr"]/div/p/text()').extract_first()
chinesereleasedate = response.xpath('//div[@class="ziliaofr"]/div/p[contains(text(),"上映时间")]/text()').extract_first())
productionregions = response.xpath('//div[@class="ziliaofr"]/div/p')[6].xpath('text()').extract_first()

为了找到chinesereleasedate,我采用了p元素,其文本包含'上映时间'。您必须解析它以获得确切的值。

为了找到productionregions,我从列表中选取了第7个选择器response.xpath('//div[@class="ziliaofr"]/div/p')[6]选择了文本。一种更好的方法是检查文本是否包含“国家及地区”,如上所述。

编辑:要回答评论中的问题,

response.xpath('//div[@class="ziliaofr"]/div/p[contains(text(),"上映时间")]/text()').extract_first()

返回一个像'\r\n 上映时间:2017-7-27(中国)\r\n '这样的字符串,这不是你想要的。你可以清理它:

chinesereleasedate = chinesereleasedate.split(':')[1].split('(')[0]

这给了我们正确的日期。


2
投票

顺便说一句,你不必用xpath折磨自己,你可以使用css:

response.css('.cont h2::text').extract_first()
# '战狼2'
response.css('.cont h2 + p::text').extract_first()
# 'Wolf Warriors 2'
© www.soinside.com 2019 - 2024. All rights reserved.