Использование Beautifulsoup для очистки веб-данных - проблемы с извлечением того, что мне нужно - PullRequest
0 голосов
/ 02 мая 2020

Я пытаюсь очистить содержимое таблицы с веб-сайта в Python с помощью BeautifulSoup, но в таблице есть несколько страниц, и я не могу понять, как очистить что-нибудь за страницей 1 в таблице. Мой текущий скрипт прекрасно работает для извлечения страницы 1 таблицы, но его страница 2 года, которую я изо всех сил пытаюсь получить.

URL страницы для вкладки 2 таблицы такой же, как и для страницы 1, поэтому не может перебирать страницы URL.

Заранее спасибо

'' 'script

import requests 
from bs4 import BeautifulSoup
import pandas as pd
import json

result = requests.get('https://www.footballindex.co.uk/players')

src = result.content

soup = BeautifulSoup(src,'lxml')

players1 = soup.find("script").text

players2 = players1.split('= ', 1)[1]

players3 = json.loads(players2)


df = pd.DataFrame(   
[item['id'],item['country'],item['nationalTeam 
,item['sector'],item['nationality'],item['team']
,item['buyPrice'],item['sellPrice'],item['penceChange']
,item['changePercent']]for item in players3['playersReducer']['players']
) 

Ответы [ 3 ]

1 голос
/ 02 мая 2020

Вы можете извлекать данные непосредственно из API JSON (и не использовать BeautifulSoup), например:

import requests
import pandas as pd

url = 'https://api-prod.footballindex.co.uk/football.allTradable24hrchanges?page={page}&per_page={per_page}&sort=asc'

page = 1
all_data = {}

while True:
    print('Processing page {}...'.format(page))

    data = requests.get(url.format(page=page, per_page=5000)).json()

    if data['count'] == 0:
        break

    # uncomment this to print all data:
    # from pprint import pprint
    # pprint(data)

    all_data.setdefault('id', []).extend(d['id'] for d in data['items'])
    all_data.setdefault('country', []).extend(d['country'] for d in data['items'])
    all_data.setdefault('nationalTeam', []).extend(d['nationalTeam'] for d in data['items'])
    all_data.setdefault('nationality', []).extend(d['nationality'] for d in data['items'])
    all_data.setdefault('team', []).extend(d['team'] for d in data['items'])
    all_data.setdefault('price', []).extend(d['price'] for d in data['items'])
    all_data.setdefault('scoreSell', []).extend(d['scoreSell'] for d in data['items'])
    all_data.setdefault('penceChange', []).extend(d['penceChange'] for d in data['items'])

    page += 1

df = pd.DataFrame(all_data)
print(df)

Отпечатки:

...
Processing page 32...
Processing page 33...
                       id      country  nationalTeam    nationality                team  price  scoreSell  penceChange
0            habib-diallo      Senegal         False        Senegal                Metz   1.19       0.71         0.09
1         sehrou-guirassy       France         False         France              Amiens   0.90       0.54         0.05
2     romain-del-castillo       France         False           None              Rennes   0.58       0.35         0.04
3          samuel-bastien      Belgium         False        Belgium      Standard Liège   0.57       0.34         0.04
4          jann-fiete-arp      Germany         False        Germany   FC Bayern München   1.43       0.86         0.03
...                   ...          ...           ...            ...                 ...    ...        ...          ...
3110      kieran-trippier      England         False        England  Atlético de Madrid   0.65       0.39        -0.01
3111        kevin-malcuit       France         False         France              Napoli   0.39       0.23        -0.01
3112       alen-halilovic      Croatia         False        Croatia       sc Heerenveen   0.36       0.22        -0.01
3113    bernardo-espinosa     Colombia         False       Colombia            Espanyol   0.18       0.11        -0.01
3114        johan-djourou  Switzerland         False  Côte d'Ivoire        Hamburger SV   0.12       0.07        -0.01

[3115 rows x 8 columns]

РЕДАКТИРОВАТЬ:

Снимок экрана firefox с URL:

enter image description here

1 голос
/ 02 мая 2020

Решение Андрея верное, но вы можете немного изменить, чтобы получить полные данные в 1 go, а затем использовать json_normalize. Просто еще один способ сделать это, чтобы вы могли видеть.

import requests
import math
from pandas.io.json import json_normalize

url = 'https://api-prod.footballindex.co.uk/football.allTradable24hrchanges'
per_page = 5000
page = 1
payload = {
'page':'%s' %page,
'per_page':'%s' %per_page,
'sort':'asc'}

print ('Gathering page: %s' %page)
jsonData = requests.get(url, params=payload).json()
total_pages = math.ceil(jsonData['total'] / per_page)

df = json_normalize(jsonData['items'])
cols = ['id', 'country', 'nationalTeam','nationality','team', 'price', 'scoreSell', 'penceChange']
df = df[cols]

if total_pages > 1:
    for page in range(2,total_pages+1):
        print ('Gathering page: %s' %page)
        payload = {
                'page':'%s' %page,
                'per_page':'%s' %per_page,
                'sort':'asc'}

        jsonData = requests.get(url, params=payload).json()
        temp_df = json_normalize(jsonData['items'])
        df = df.append(temp_df[cols], sort=False).reset_index(drop=True)
0 голосов
/ 02 мая 2020

Проверьте сайт. если страницы: {https://www.footballindex.co.uk/players/1, https://www.footballindex.co.uk/players/2, https://www.footballindex.co.uk/players/3 ...} Сделать часть кода для повторения на всех страницах

page = 0       
for i in range(1,n): #will iterate till n-1 page
    page = i
    result = requests.get('https://www.footballindex.co.uk/players'+str(page))

    src = result.content

    soup = BeautifulSoup(src,'lxml')

    players1 = soup.find("script").text

    players2 = players1.split('= ', 1)[1]

    players3 = json.loads(players2)


    df = pd.DataFrame(   
    [item['id'],item['country'],item['nationalTeam 
    ,item['sector'],item['nationality'],item['team']
    ,item['buyPrice'],item['sellPrice'],item['penceChange']
    ,item['changePercent']]for item in players3['playersReducer']['players']
    ) 

как то так

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...