Web Scraping с Try: Except: в цикле - PullRequest
       5

Web Scraping с Try: Except: в цикле

0 голосов
/ 02 января 2019

Я написал приведенный ниже код, пытаясь практиковаться в просмотре веб-страниц с помощью Python, Pandas и т. Д. В целом у меня есть четыре шага, которые я пытаюсь выполнить для достижения желаемого результата:

  1. Получить список имен для добавления в базовый URL
  2. Создать список специфичных для игрока URL
  3. Используйте URL-адреса игроков для очистки таблиц
  4. добавить имя игрока в таблицу, которую я вычеркнул, чтобы отследить, какой игрок принадлежит к какой статистике - поэтому в каждом ряду таблицы добавьте столбец с именем игрока, который использовался для очистки таблицы

Мне удалось заставить # 1 и 2 работать. Компоненты # 3, кажется, работают, но я полагаю, что у меня что-то не так с моей попыткой: за исключением того, что если я запускаю только строку кода, чтобы очистить определенный playerUrl, таблицы DF заполняются, как и ожидалось. У первого игрока нет данных, поэтому я считаю, что мне не удается поймать ошибку.

Для # 4 я действительно не смог найти решение. Как добавить имя в список, поскольку оно повторяется в цикле for?

Любая помощь приветствуется.

import requests
import pandas as pd
from bs4 import BeautifulSoup



### get the player data to create player specific urls

res = requests.get("https://www.mlssoccer.com/players?page=0")
soup = BeautifulSoup(res.content,'html.parser')
data = soup.find('div', class_ = 'item-list' )

names=[]


for player in data:
    name = data.find_all('div', class_ = 'name')
    for obj in name:
        names.append(obj.find('a').text.lower().lstrip().rstrip().replace(' ','-'))


### create a list of player specific urls
url = 'https://www.mlssoccer.com/players/'
playerUrl = []
x = 0
for name in (names):
    playerList = names
    newUrl = url + str(playerList[x])
    print("Gathering url..."+newUrl)
    playerUrl.append(newUrl)
    x +=1

### now take the list of urls and gather stats tables

tbls = []
i = 0
for url in (playerUrl):
    try:                                                        ### added the try, except, pass because some players have no stats table
        tables = pd.read_html(playerUrl[i], header = 0)[2]
        tbls.append(tables)
        i +=1
    except Exception:
        continue

Ответы [ 2 ]

0 голосов
/ 02 января 2019

В вашем скрипте много избыточности. Вы можете очистить их, соблюдая следующее. Я использовал select() вместо find_all(), чтобы сначала избавиться от многословия. Чтобы избавиться от этого IndexError, вы можете использовать ключевое слово continue, как я показал ниже:

import requests
import pandas as pd
from bs4 import BeautifulSoup

base_url = "https://www.mlssoccer.com/players?page=0"
url = 'https://www.mlssoccer.com/players/'

res = requests.get(base_url)
soup = BeautifulSoup(res.text,'lxml')
names = []
for player in soup.select('.item-list .name a'):
    names.append(player.get_text(strip=True).replace(" ","-"))

playerUrl = {}
for name in names:
    playerUrl[name] = f'{url}{name}'

tbls = []
for url in playerUrl.values():
    if len(pd.read_html(url))<=2:continue
    tables = pd.read_html(url, header=0)[2]
    tbls.append(tables)

print(tbls)
0 голосов
/ 02 января 2019

Вы можете сделать несколько вещей, чтобы улучшить свой код и выполнить шаги 3 и 4.

(i) При использовании цикла for name in names нет необходимости явно использовать индексацию, просто используйте имя переменной. (ii) Вы можете сохранить имя игрока и соответствующий ему URL-адрес в виде комментария, где имя является ключом. Затем на шаге 3/4 вы можете использовать это имя (iii) Создайте DataFrame для каждой проанализированной HTML-таблицы и просто добавьте к ней имя игрока. Сохраните этот фрейм данных индивидуально.
(iv) Наконец объединить эти кадры данных, чтобы сформировать один.

Вот ваш код, модифицированный вышеуказанными изменениями:

import requests
import pandas as pd
from bs4 import BeautifulSoup



### get the player data to create player specific urls

res = requests.get("https://www.mlssoccer.com/players?page=0")
soup = BeautifulSoup(res.content,'html.parser')
data = soup.find('div', class_ = 'item-list' )

names=[]

for player in data:
    name = data.find_all('div', class_ = 'name')
    for obj in name:
        names.append(obj.find('a').text.lower().lstrip().rstrip().replace(' ','-'))


### create a list of player specific urls
url = 'https://www.mlssoccer.com/players/'
playerUrl = {}
x = 0
for name in names:
    newUrl = url + str(name)
    print("Gathering url..."+newUrl)
    playerUrl[name] = newUrl

### now take the list of urls and gather stats tables

tbls = []
for name, url in playerUrl.items():
    try:                                                        
        tables = pd.read_html(url, header = 0)[2]
        df = pd.DataFrame(tables)
        df['Player'] = name
        tbls.append(df)
    except Exception as e:
        print(e)
        continue

result = pd.concat(tbls)
print(result.head())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...