Как исправить / предотвратить проблему перезаписи данных в Web Scrape L oop? - PullRequest
1 голос
/ 04 марта 2020

Мне удалось l oop процесс очистки веб-страниц, но данные, собранные на следующей странице, заменяют данные на предыдущей странице. Создание Excel содержит только данные с последней страницы. Что мне нужно сделать?

from bs4 import BeautifulSoup
import requests
import pandas as pd
print ('all imported successfuly')


for x in range(1, 44):
    link = (f'https://www.trustpilot.com/review/birchbox.com?page={x}')
    print (link)
    req = requests.get(link)
    content = req.content
    soup = BeautifulSoup(content, "lxml")
    names = soup.find_all('div', attrs={'class': 'consumer-information__name'})
    headers = soup.find_all('h2', attrs={'class':'review-content__title'})
    bodies = soup.find_all('p', attrs={'class':'review-content__text'})
    ratings = soup.find_all('div', attrs={'class':'star-rating star-rating--medium'})
    dates = soup.find_all('div', attrs={'class':'review-content-header__dates'})


print ('pass1')

df = pd.DataFrame({'User Name': names, 'Header': headers, 'Body': bodies, 'Rating': ratings, 'Date': dates})
df.to_csv('birchbox006.csv', index=False, encoding='utf-8')
print ('excel done')

Ответы [ 3 ]

1 голос
/ 04 марта 2020

Поскольку вы используете al oop, переменные постоянно перезаписываются. Обычно то, что вы делаете в такой ситуации, - это массив, а затем добавление к нему по всей l oop:

from bs4 import BeautifulSoup
import requests
import pandas as pd
import json
print ('all imported successfuly')

# Initialize an empty dataframe
df = pd.DataFrame()
for x in range(1, 44):
    names = []
    headers = []
    bodies = []
    ratings = []  
    published = []
    updated = []
    reported = []

    link = (f'https://www.trustpilot.com/review/birchbox.com?page={x}')
    print (link)
    req = requests.get(link)
    content = req.content
    soup = BeautifulSoup(content, "lxml")
    articles = soup.find_all('article', {'class':'review'})
    for article in articles:
        names.append(article.find('div', attrs={'class': 'consumer-information__name'}).text.strip())
        headers.append(article.find('h2', attrs={'class':'review-content__title'}).text.strip())
        try:
            bodies.append(article.find('p', attrs={'class':'review-content__text'}).text.strip())
        except:
            bodies.append('')

        try:
            ratings.append(article.find('p', attrs={'class':'review-content__text'}).text.strip())
        except:
            ratings.append('')
        dateElements = article.find('div', attrs={'class':'review-content-header__dates'}).text.strip()

        jsonData = json.loads(dateElements)
        published.append(jsonData['publishedDate'])
        updated.append(jsonData['updatedDate'])
        reported.append(jsonData['reportedDate'])


    # Create your temporary dataframe of the first iteration, then append that into your "final" dataframe
    temp_df = pd.DataFrame({'User Name': names, 'Header': headers, 'Body': bodies, 'Rating': ratings, 'Published Date': published, 'Updated Date':updated, 'Reported Date':reported})
    df = df.append(temp_df, sort=False).reset_index(drop=True)

print ('pass1')


df.to_csv('birchbox006.csv', index=False, encoding='utf-8')
print ('excel done')
1 голос
/ 04 марта 2020

Причина в том, что вы перезаписываете свои переменные в каждой итерации. Если вы хотите расширить эти переменные, вы можете сделать, например:

names = []
bodies = []
ratings = []
dates = []
for x in range(1, 44):
    link = (f'https://www.trustpilot.com/review/birchbox.com?page={x}')
    print (link)
    req = requests.get(link)
    content = req.content
    soup = BeautifulSoup(content, "lxml")
    names += soup.find_all('div', attrs={'class': 'consumer-information__name'})
    headers += soup.find_all('h2', attrs={'class':'review-content__title'})
    bodies += soup.find_all('p', attrs={'class':'review-content__text'})
    ratings += soup.find_all('div', attrs={'class':'star-rating star-rating--medium'})
    dates += soup.find_all('div', attrs={'class':'review-content-header__dates'})
1 голос
/ 04 марта 2020

Вам нужно будет хранить эти данные после каждой итерации. Есть несколько способов сделать это. Вы можете просто сохранить все в списке, а затем создать свой фрейм данных. Или я создал «временный» фрейм данных, который создается после каждой итерации, а затем добавляю его в финальный фрейм данных. Думайте об этом как о спасении воды. У вас есть маленькое ведро воды, чтобы затем опустошить его в большое ведро, которое будет собирать / удерживать всю воду, которую вы пытаетесь собрать.

from bs4 import BeautifulSoup
import requests
import pandas as pd
import json
print ('all imported successfuly')

# Initialize an empty dataframe
df = pd.DataFrame()
for x in range(1, 44):
    published = []
    updated = []
    reported = []

    link = (f'https://www.trustpilot.com/review/birchbox.com?page={x}')
    print (link)
    req = requests.get(link)
    content = req.content
    soup = BeautifulSoup(content, "lxml")
    names = [ x.text.strip() for x in soup.find_all('div', attrs={'class': 'consumer-information__name'})]
    headers = [ x.text.strip() for x in soup.find_all('h2', attrs={'class':'review-content__title'})]
    bodies = [ x.text.strip() for x in soup.find_all('p', attrs={'class':'review-content__text'})]
    ratings = [ x.text.strip() for x in soup.find_all('div', attrs={'class':'star-rating star-rating--medium'})]
    dateElements = soup.find_all('div', attrs={'class':'review-content-header__dates'})
    for date in dateElements:
        jsonData = json.loads(date.text.strip())
        published.append(jsonData['publishedDate'])
        updated.append(jsonData['updatedDate'])
        reported.append(jsonData['reportedDate'])


    # Create your temporary dataframe of the first iteration, then append that into your "final" dataframe
    temp_df = pd.DataFrame({'User Name': names, 'Header': headers, 'Body': bodies, 'Rating': ratings, 'Published Date': published, 'Updated Date':updated, 'Reported Date':reported})
    df = df.append(temp_df, sort=False).reset_index(drop=True)

print ('pass1')


df.to_csv('birchbox006.csv', index=False, encoding='utf-8')
print ('excel done')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...