Python 中的 Web Scryping

Web Scryping in Python

我正试图为某个大学项目抓取一个网站。该网站是 https://www.bonprix.it/prodotto/leggings-a-pinocchietto-pacco-da-2-leggings-a-pinocchietto-pacco-da-2-bianco-nero-956015/?itemOptionId=12211813。 我的 python 代码有问题。我想获得的是从 1 到 5 页的所有评论,但我得到了所有 []。任何帮助将不胜感激!

代码如下:

import csv
from bs4 import BeautifulSoup
import urllib.request
import re
import pandas as pd
import requests
reviewlist = []
class AppURLopener(urllib.request.FancyURLopener):
    version = "Mozilla/5.0"

opener = AppURLopener()
response = opener.open('https://www.bonprix.it/prodotto/leggings-a-pinocchietto-pacco-da-2-leggings-a-pinocchietto-pacco-da-2-bianco-nero-956015/?itemOptionId=12211813')

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

reviews = soup.find_all('div',{'class':'reviewContent'})


for i in reviews:
    review = {

        'per_review_name' : i.find('span',{'itemprop':'name'}).text.strip(),
        'per_review' : i.find('p',{'class':'reviewText'}).text.strip(),
        'per_review_taglia' : i.find('p',{'class':'singleReviewSizeDescr'}).text.strip(),
        
    }
    reviewlist.append(review)
   
for page in range (1,5):
    prova = soup.find_all('div',{'data-page': '{page}'})
    print(prova)
    print(len(reviewlist))
        
df = pd.DataFrame(reviewlist)
df.to_csv('list.csv',index=False)
print('Fine.')

这是我得到的输出:

[]
5
[]
5
[]
5
[]
5
Fine.

据我了解,该网站使用 Javascript 来加载其大部分内容,因此您无法抓取该数据,因为它最初并未加载,但您可以使用产品网站的评级后端link 是:

https://www.bonprix.it/reviews/list/?styleId=31436999&sortby=date&page=1&rating=0&variant=0&size=0&bodyHeight=0&showOldReviews=true&xxl=false&variantFilters=

您可以通过更改 url/get 请求中的页面参数来浏览页面,link returns 评级页面的 html 文档,您可以从评分值元标记中获取评分

该网站仅在第一个请求中加载评论的第一页。如果你检查它的请求,你可以看到它在你更改评论页面时请求额外的数据。您可以按如下方式重写代码以获取所有页面的评论:

reviews_dom = []
for page in range(1,6):
    url = f"https://www.bonprix.it/reviews/list/?styleId=31436999&sortby=date&page={page}&rating=0&variant=0&size=0&bodyHeight=0&showOldReviews=true&xxl=false&variantFilters="
    r = requests.request("GET", url)
    soup = BeautifulSoup(r.text, "html.parser")
    reviews_dom += soup.find_all("div", attrs={"class": "reviewContent"})
    
reviews = []
for review_item in reviews_dom:
    review = {
        'per_review_name' : review_item.find('span', attrs={'itemprop':'name'}).text.strip(),
        'per_review' : review_item.find('p', attrs={'class':'reviewText'}).text.strip(),
        'per_review_taglia' : review_item.find('p', attrs={'class':'singleReviewSizeDescr'}).text.strip(),
    }
    reviews.append(review)
    
print(len(reviews))
print(reviews)

代码中发生了什么?

在第一次迭代中,我们请求每页评论的数据(上例中的前 5 页)。

在第二次迭代中,我们解析评论 dom 并提取我们需要的数据。