【发布时间】:2021-02-24 06:21:51
【问题描述】:
我试图在 Tripadvisor 中抓取多家酒店的评论,并且能够抓取包含 150 次观察的数据,其中包含来自 30 家酒店的 150 条评论数据。 p>
但是,当我尝试添加 hotel_name 的新列并执行爬网时,酒店名称不会再次出现,并且观察次数减少到酒店数量为 30。如何使酒店名称重复到每个评论行的?
这是我正在使用的代码:
import scrapy
from..items import ReviewItem
import re
class TripAdvisorReview(scrapy.Spider):
name = "tripadvisor"
start_urls = ["https://www.tripadvisor.co.uk/Hotels-g186217-England-Hotels.html"]
def parse(self, response):
for href in response.css("div.listing_title a::attr('href')"):
url = response.urljoin(href.extract())
yield scrapy.Request(url, callback=self.parse_hotel)
def parse_hotel(self, response):
for info in response.css('div.page'):
items = ReviewItem()
hotel_names = info.css('._1mTlpMC3::text').extract()
hotel_names = [hotel_name.strip() for hotel_name in hotel_names]
reviewer_names = info.css('._1r_My98y::text').extract()
reviewer_names = [reviewer_name.strip() for reviewer_name in reviewer_names]
reviewer_contributions = info.css('._3fPsSAYi:nth-child(1) ._1fk70GUn , ._1TuWwpYf+ ._3fPsSAYi ._1fk70GUn').css('::text').extract()
reviewer_contributions = [reviewer_contribution.strip() for reviewer_contribution in reviewer_contributions]
review_dates = info.xpath('//div[@class = "_2fxQ4TOx"]/span[contains(text(),"wrote a review")]/text()').extract()
review_dates = [review_date.strip() for review_date in review_dates]
review_stars = info.css('div.nf9vGX55 .ui_bubble_rating').xpath("@class").extract()
review_stars = [review_star.strip() for review_star in review_stars]
review_texts = info.css('#component_15 .cPQsENeY').css('::text').extract()
review_texts = [review_text.strip() for review_text in review_texts]
#helpful_vote = info.css('._3kbymg8R::text').extract()
result = zip(hotel_names, reviewer_names, review_dates, review_texts, review_stars, reviewer_contributions)
for hotel_name, reviewer_name, review_date, review_text, review_star, reviewer_contribution in result:
items['hotel_name'] = hotel_name
items['reviewer_name'] = reviewer_name
items['reviewer_contribution'] = reviewer_contribution
items['review_date'] = review_date
items['review_star'] = review_star
items['review_text'] = review_text
#items['helpful_vote'] = helpful_vote
yield items
【问题讨论】:
-
如果您希望
for-loop 中有更多项目,那么您应该为结果创建列表,而不是result,它只能保留单个结果。或者你应该在第一个for-loop 中使用第二个for-loop。只是你有错误的缩进。 -
顺便说一句:有时单独搜索元素,然后用
zip()加入它们可能会给出错误的结果。当一个项目没有即。stars然后它不会把None放在这个地方,但它会从这个地方的下一个元素移动stars。 -
您可以使用
print()查看变量中的内容 - 尤其是在第二个for-loop 之前的result中 - 它只会使用第一个for-loop 中的最后一个result. -
问题也可以是
zip()。您的hotel_names只有一个值,但像reviewer_names这样的其他变量有 5 个值 - 但zip()将使用最短列表,因此它只会创建一项。您应该使用zip()而不使用hotel_names,然后手动将此名称添加到每个item['hotel_name']