Scrapy, Crawling Reviews on Tripadvisor:提取更多酒店和用户信息
Scrapy, Crawling Reviews on Tripadvisor: extract more hotel and user information
需要从 tripAdvisor 提取更多信息
我的代码:
item = TripadvisorItem()
item['url'] = response.url.encode('ascii', errors='ignore')
item['state'] = hxs.xpath('//*[@id="PAGE"]/div[2]/div[1]/ul/li[2]/a/span/text()').extract()[0].encode('ascii', errors='ignore')
if(item['state']==[]):
item['state']=hxs.xpath('//*[@id="HEADING_GROUP"]/div[2]/address/span/span/span[contains(@class,"region_title")][2]/text()').extract()
item['city'] = hxs.select('//*[@id="PAGE"]/div[2]/div[1]/ul/li[3]/a/span/text()').extract()
if(item['city']==[]):
item['city'] =hxs.xpath('//*[@id="HEADING_GROUP"]/div[2]/address/span/span/span[1]/span/text()').extract()
if(item['city']==[]):
item['city']=hxs.xpath('//*[@id="HEADING_GROUP"]/div[2]/address/span/span/span[3]/span/text()').extract()
item['city']= item['city'][0].encode('ascii', errors='ignore')
item['hotelName'] = hxs.xpath('//*[@id="HEADING"]/span[2]/span/a/text()').extract()
item['hotelName']=item['hotelName'][0].encode('ascii', errors='ignore')
reviews = hxs.select('.//div[contains(@id, "review")]')
1。对于 tripAdvisor 中的每家酒店,都有酒店的 ID 号。喜欢这家酒店的 80075:http://www.tripadvisor.com/Hotel_Review-g60763-d80075-Reviews-Amsterdam_Court_Hotel-New_York_City_New_York.html#REVIEWS
如何从 TA 项目中提取此 ID?
我需要每家酒店的更多信息:简短描述、星级、邮政编码、国家和坐标(长、纬度)。我可以提取这些东西吗?
我需要为每条评论提取旅客类型。如何?
我的审核代码:
for review in reviews:
it = Review()
it['state'] = item['state']
it['city'] = item['city']
it['hotelName'] = item['hotelName']
it['date'] = review.xpath('.//div[1]/div[2]/div/div[2]/span[2]/@title').extract()
if(it['date']==[]):
it['date']=review.xpath('.//div[1]/div[2]/div/div[2]/span[2]/text()').extract()
if(it['date']!=[]):
it['date']=it['date'][0].encode('ascii', errors='ignore').replace("Reviewed","").strip()
it['userName'] = review.xpath('.//div[contains(@class,"username mo")]/span/text()').extract()
if (it['userName']!=[]):
it['userName']=it['userName'][0].encode('ascii', errors='ignore')
it['userLocation'] = ''.join(review.xpath('.//div[contains(@class,"location")]/text()').extract()).strip().encode('ascii', errors='ignore')
it['reviewTitle'] = review.xpath('.//div[1]/div[2]/div[1]/div[contains(@class,"quote")]/text()').extract()
if(it['reviewTitle']!=[]):
it['reviewTitle']=it['reviewTitle'][0].encode('ascii', errors='ignore')
else:
it['reviewTitle'] = review.xpath('.//div[1]/div[2]/div/div[1]/a/span[contains(@class,"noQuotes")]/text()').extract()
if(it['reviewTitle']!=[]):
it['reviewTitle']=it['reviewTitle'][0].encode('ascii', errors='ignore')
it['reviewContent'] = review.xpath('.//div[1]/div[2]/div[1]/div[3]/p/text()').extract()
if(it['reviewContent']!=[]):
it['reviewContent']=it['reviewContent'][0].encode('ascii', errors='ignore').strip()
it['generalRating'] = review.xpath('.//div/div[2]/div/div[2]/span[1]/img/@alt').extract()
if(it['generalRating']!=[]):
it['generalRating'] =it['generalRating'][0].encode('ascii', errors='ignore').split()[0]
有没有好的手册怎么找这些东西?我迷失了所有的跨度和 div..
谢谢!
使用正则表达式从 URL 获取它是否可以接受?
id = re.search('(-d)([0-9]+)',url).group(2)
我将尝试在纯 XPath 中执行此操作。不幸的是,您想要的大部分信息似乎都包含在 <script>
个标签中:
酒店编号 - Returns“80075”
substring-before(normalize-space(substring-after(//script[contains(., "geoId:") and contains(., "lat")]/text(), "locId:")), ",")
或者,酒店 ID 在 URL 中,正如另一位回答者所提到的。如果您确定格式始终相同(例如在 ID 前包含“d”),则可以改用它。
评级(顶部的那个)- Returns“3.5”
//span[contains(@class, "rating_rr")]/img/@content
此页面上有几个评级实例。顶部的主要评级是我在这里抓住的。我没有在 Scrapy 中测试过它,所以它可能是由 JavaScript 填充的,而不是最初作为 HTML 的一部分加载的。如果是这种情况,您需要在其他地方获取它或使用 Selenium/PhantomJS.
之类的东西
邮政编码 - Returns“10019”
(//span[@property="v:postal-code"]/text())[1]
同样,同上。它在 HTML 中,但您应该在页面加载时检查它是否存在。
国家/地区 - Returns“美国”
substring-before(substring-after(//script[contains(., "modelLocaleCountry")]/text(), "modelLocaleCountry = "), ";")
这个带有引号。您始终可以(并且您应该)使用管道来清理抓取的数据,使其看起来像您想要的那样。
坐标 - Returns 分别为“40.76174”和“-73.985275”
纬度:substring-before(normalize-space(substring-after(//script[contains(., "geoId:") and contains(., "lat")]/text(), "lat:")), ",")
朗:substring-before(normalize-space(substring-after(//script[contains(., "geoId:") and contains(., "lat")]/text(), "lng:")), ",")
我不完全确定此页面上的简短说明在哪里,所以我没有包含它。您可能必须导航到其他地方才能获取它。我也不是 100% 确定“旅行者类型”是什么意思,所以我会把那个留给你。
就手册而言,它确实与练习有关。您将学习在 XPath 中工作的技巧和技巧,并且 Scrapy 允许您使用一些附加功能,例如正则表达式和管道。我不建议执行整个“绝对路径”XPath(即 ./div/div[3]/div[2]/ul/li[3]/...
),因为 DOM 中的任何偏差都会完全破坏您的抓取。如果您有大量数据要抓取,并且您计划将其保留一段时间,那么如果任何站点移动甚至单个 <div>
.
,您的项目将很快变得难以管理。
我建议使用更多“查询”XPath,例如 //div[contains(@class, "foo")]//a[contains(@href, "detailID")]
。这样的路径将确保无论元素之间放置多少元素,您都知道它们会在那里,即使多个目标元素彼此略有不同,您也能够一致地抓取它们。
XPath 需要大量的试验和错误。很多。以下是一些对我有很大帮助的工具:
- XPath Helper(Chrome 分机)
scrapy shell <URL>
scrapy view <URL>
(用于在浏览器中渲染 Scrapy 的响应)
- PhantomJS(如果您有兴趣获取通过 JavaScript 插入的数据)
希望以上内容有所帮助。
需要从 tripAdvisor 提取更多信息
我的代码:
item = TripadvisorItem()
item['url'] = response.url.encode('ascii', errors='ignore')
item['state'] = hxs.xpath('//*[@id="PAGE"]/div[2]/div[1]/ul/li[2]/a/span/text()').extract()[0].encode('ascii', errors='ignore')
if(item['state']==[]):
item['state']=hxs.xpath('//*[@id="HEADING_GROUP"]/div[2]/address/span/span/span[contains(@class,"region_title")][2]/text()').extract()
item['city'] = hxs.select('//*[@id="PAGE"]/div[2]/div[1]/ul/li[3]/a/span/text()').extract()
if(item['city']==[]):
item['city'] =hxs.xpath('//*[@id="HEADING_GROUP"]/div[2]/address/span/span/span[1]/span/text()').extract()
if(item['city']==[]):
item['city']=hxs.xpath('//*[@id="HEADING_GROUP"]/div[2]/address/span/span/span[3]/span/text()').extract()
item['city']= item['city'][0].encode('ascii', errors='ignore')
item['hotelName'] = hxs.xpath('//*[@id="HEADING"]/span[2]/span/a/text()').extract()
item['hotelName']=item['hotelName'][0].encode('ascii', errors='ignore')
reviews = hxs.select('.//div[contains(@id, "review")]')
1。对于 tripAdvisor 中的每家酒店,都有酒店的 ID 号。喜欢这家酒店的 80075:http://www.tripadvisor.com/Hotel_Review-g60763-d80075-Reviews-Amsterdam_Court_Hotel-New_York_City_New_York.html#REVIEWS
如何从 TA 项目中提取此 ID?
我需要每家酒店的更多信息:简短描述、星级、邮政编码、国家和坐标(长、纬度)。我可以提取这些东西吗?
我需要为每条评论提取旅客类型。如何? 我的审核代码:
for review in reviews: it = Review() it['state'] = item['state'] it['city'] = item['city'] it['hotelName'] = item['hotelName'] it['date'] = review.xpath('.//div[1]/div[2]/div/div[2]/span[2]/@title').extract() if(it['date']==[]): it['date']=review.xpath('.//div[1]/div[2]/div/div[2]/span[2]/text()').extract() if(it['date']!=[]): it['date']=it['date'][0].encode('ascii', errors='ignore').replace("Reviewed","").strip() it['userName'] = review.xpath('.//div[contains(@class,"username mo")]/span/text()').extract() if (it['userName']!=[]): it['userName']=it['userName'][0].encode('ascii', errors='ignore') it['userLocation'] = ''.join(review.xpath('.//div[contains(@class,"location")]/text()').extract()).strip().encode('ascii', errors='ignore') it['reviewTitle'] = review.xpath('.//div[1]/div[2]/div[1]/div[contains(@class,"quote")]/text()').extract() if(it['reviewTitle']!=[]): it['reviewTitle']=it['reviewTitle'][0].encode('ascii', errors='ignore') else: it['reviewTitle'] = review.xpath('.//div[1]/div[2]/div/div[1]/a/span[contains(@class,"noQuotes")]/text()').extract() if(it['reviewTitle']!=[]): it['reviewTitle']=it['reviewTitle'][0].encode('ascii', errors='ignore') it['reviewContent'] = review.xpath('.//div[1]/div[2]/div[1]/div[3]/p/text()').extract() if(it['reviewContent']!=[]): it['reviewContent']=it['reviewContent'][0].encode('ascii', errors='ignore').strip() it['generalRating'] = review.xpath('.//div/div[2]/div/div[2]/span[1]/img/@alt').extract() if(it['generalRating']!=[]): it['generalRating'] =it['generalRating'][0].encode('ascii', errors='ignore').split()[0]
有没有好的手册怎么找这些东西?我迷失了所有的跨度和 div..
谢谢!
使用正则表达式从 URL 获取它是否可以接受?
id = re.search('(-d)([0-9]+)',url).group(2)
我将尝试在纯 XPath 中执行此操作。不幸的是,您想要的大部分信息似乎都包含在 <script>
个标签中:
酒店编号 - Returns“80075”
substring-before(normalize-space(substring-after(//script[contains(., "geoId:") and contains(., "lat")]/text(), "locId:")), ",")
或者,酒店 ID 在 URL 中,正如另一位回答者所提到的。如果您确定格式始终相同(例如在 ID 前包含“d”),则可以改用它。
评级(顶部的那个)- Returns“3.5”
//span[contains(@class, "rating_rr")]/img/@content
此页面上有几个评级实例。顶部的主要评级是我在这里抓住的。我没有在 Scrapy 中测试过它,所以它可能是由 JavaScript 填充的,而不是最初作为 HTML 的一部分加载的。如果是这种情况,您需要在其他地方获取它或使用 Selenium/PhantomJS.
之类的东西邮政编码 - Returns“10019”
(//span[@property="v:postal-code"]/text())[1]
同样,同上。它在 HTML 中,但您应该在页面加载时检查它是否存在。
国家/地区 - Returns“美国”
substring-before(substring-after(//script[contains(., "modelLocaleCountry")]/text(), "modelLocaleCountry = "), ";")
这个带有引号。您始终可以(并且您应该)使用管道来清理抓取的数据,使其看起来像您想要的那样。
坐标 - Returns 分别为“40.76174”和“-73.985275”
纬度:substring-before(normalize-space(substring-after(//script[contains(., "geoId:") and contains(., "lat")]/text(), "lat:")), ",")
朗:substring-before(normalize-space(substring-after(//script[contains(., "geoId:") and contains(., "lat")]/text(), "lng:")), ",")
我不完全确定此页面上的简短说明在哪里,所以我没有包含它。您可能必须导航到其他地方才能获取它。我也不是 100% 确定“旅行者类型”是什么意思,所以我会把那个留给你。
就手册而言,它确实与练习有关。您将学习在 XPath 中工作的技巧和技巧,并且 Scrapy 允许您使用一些附加功能,例如正则表达式和管道。我不建议执行整个“绝对路径”XPath(即 ./div/div[3]/div[2]/ul/li[3]/...
),因为 DOM 中的任何偏差都会完全破坏您的抓取。如果您有大量数据要抓取,并且您计划将其保留一段时间,那么如果任何站点移动甚至单个 <div>
.
我建议使用更多“查询”XPath,例如 //div[contains(@class, "foo")]//a[contains(@href, "detailID")]
。这样的路径将确保无论元素之间放置多少元素,您都知道它们会在那里,即使多个目标元素彼此略有不同,您也能够一致地抓取它们。
XPath 需要大量的试验和错误。很多。以下是一些对我有很大帮助的工具:
- XPath Helper(Chrome 分机)
scrapy shell <URL>
scrapy view <URL>
(用于在浏览器中渲染 Scrapy 的响应)- PhantomJS(如果您有兴趣获取通过 JavaScript 插入的数据)
希望以上内容有所帮助。