我正在设置我的第一个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()
以下是一些示例,您可以从中推断出最后一个示例。请记住始终使用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]
这给了我们正确的日期。
顺便说一句,你不必用xpath折磨自己,你可以使用css:
response.css('.cont h2::text').extract_first()
# '战狼2'
response.css('.cont h2 + p::text').extract_first()
# 'Wolf Warriors 2'