Web Scraping - повторение - PullRequest
       2

Web Scraping - повторение

1 голос
/ 26 октября 2019

Я ищу, чтобы почистить веб-сайт гостиничной платформы для обзоров. Я не могу понять две вещи: 1 - Почему я не могу извлечь все отзывы одновременно? Скажем, есть 14 отзывов, я получаю только 7 из них или около того. Я предполагаю, что существует ограничение на сервер, на котором размещен веб-сайт?

2 - Когда я перебираю объект review_list, извлекаемые дочерние объекты каждый раз одинаковы - то есть я получаю одинаковые review_item. Вместо того, чтобы перебирать различные объекты, это tag li и class review_item (см. Второй фрагмент кода).

Я использую Python 3.7, и пример URL: пример URL Надеюсь, вы сможете пролить немного света здесь.

Спасибо!

Фрагмент кода 1:

import urllib.request, urllib.parse, urllib.error
from bs4 import BeautifulSoup
import ssl
import json
import re
import sys
import warnings 
if not sys.warnoptions:
    warnings.simplefilter("ignore")#For ignoring SSL certificate errors
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE# url = input('Enter url - ' )
url=input("Enter Url - ")
html = urllib.request.urlopen(url, context=ctx).read()

soup = BeautifulSoup(html, 'html.parser')

html = soup.prettify("utf-8")

hotel_json_details = {}
hotel_json = {}
for line in soup.find_all('script',attrs={"type" : "application/ld+json"}):
    details = line.text.strip()
    details = json.loads(details)
    hotel_json_details["name"] = details["name"]
    hotel_json_details["aggregateRating"]={}
    hotel_json_details["aggregateRating"]["ratingValue"]=details["aggregateRating"]["ratingValue"]
    hotel_json_details["aggregateRating"]["reviewCount"]=details["aggregateRating"]["reviewCount"]
    hotel_json_details["address"]={}
    hotel_json_details["address"]["Street"]=details["address"]["streetAddress"]
    hotel_json_details["address"]["Locality"]=details["address"]["addressLocality"]
    hotel_json_details["address"]["Region"]=details["address"]["addressRegion"]
    hotel_json_details["address"]["Zip"]=details["address"]["postalCode"]
    hotel_json_details["address"]["Country"]=details["address"]["addressCountry"]

print(hotel_json_details)

div = soup.find_all(['li'],attrs={"class" : "review_item"})
print(div)

Фрагмент кода 2:

hotel_reviews= []
for line in soup.find_all('li', class_='review_item'): 
    review={}
    review["review_metadata"]={}
    review["review"]={}

    review["review_metadata"]["review_date"] = soup.find('p', class_='review_item_date').text.strip()
    review["review_metadata"]["review_staydate"] = soup.find('p', class_='review_staydate').text.strip()
    review["review_metadata"]["reviewer_name"] = soup.find('p', class_='reviewer_name').text.strip()
    review["review_metadata"]["reviewer_country"] = soup.find('span', class_='reviewer_country').text.strip()
    review["review_metadata"]["reviewer_score"] = soup.find('span', class_='review-score-badge').text.strip()
    review["review"]["review_pos"] = soup.find('p', class_='review_pos').text.strip()
    review["review"]["review_neg"] = soup.find('p', class_='review_neg').text.strip()
    scoreword = soup.find('span', class_='review_item_header_scoreword')
    if scoreword != None :
        review["review_metadata"]["review_header"] = scoreword.text.strip()
    else:
        review["review_metadata"]["review_header"] = ""
    hotel_reviews.append(x)
print(hotel_reviews)

1 Ответ

2 голосов
/ 26 октября 2019

Когда вы перебираете элементы обзора, вам нужно использовать line.find() вместо soup.find(). Таким образом, вы будете искать поля обзора внутри каждого контейнера обзора, а не искать по всему дереву HTML:

for line in soup.find_all('li', class_='review_item'): 
    review = {"review_metadata": {}, "review": {}}

    review["review_metadata"]["review_date"] = line.find('p', class_='review_item_date').text.strip()
    #                                          ^ HERE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...