Очистка нескольких страниц с помощью BeautifulSoup и dataframe iterrows - PullRequest
0 голосов
/ 11 ноября 2018

Я использую BeautifulSoup, чтобы очистить несколько URL-адресов.URL повторяется путем добавления переменной, которую я сохранил в кадре данных (postcode_URL).

Код разбивается на строку: table_rows = table.find_all('tr'), выдает ошибку: у объекта 'NoneType' нет атрибута 'find_all'

Интересно, что код работает отлично, если я удаляю итерацию и вручную вводю один почтовый индекс в URL, поэтому я считаю, что это должно быть как-то связано с циклом итерации.

Ниже приведен код, который ябыло использовано.Есть идеи?

scraped_data = []

for x, row in postcodes_for_urls.iterrows():
    page = requests.get("http://myurl"+(row['postcode_URL']))
    soup = BeautifulSoup(page.content, 'html.parser')
    table = soup.find('table')
    table_rows = table.find_all('tr')
    for tr in table_rows:
        td = tr.find_all('td')
        row = [tr.text for tr in td]
        scraped_data.append(row)

pd.DataFrame(scraped_data, columns=["A", "B", "C"])

Ответы [ 2 ]

0 голосов
/ 11 ноября 2018

Все, что вам нужно, это поставить отметку на table_rows, если она отсутствует и не пуста, попробуйте следующий код.Вы также можете поместить exception handler как try и catch для лучших практик.Он всегда ломается из-за пустой строки или из-за необычного шаблона на реальной странице, которую вы просматриваете.

scraped_data = []

for x, row in postcodes_for_urls.iterrows():
    page = requests.get("http://myurl"+(row['postcode_URL']))
    soup = BeautifulSoup(page.content, 'html.parser')
    table = soup.find('table')

    if table is not None and len(table.find_all('tr'))>0:
        table_rows = table.find_all('tr')
        for tr in table_rows:
            td = tr.find_all('td')
            row = [tr.text for tr in td]
            scraped_data.append(row)
    else:
        scraped_data.append('EMPTY')

pd.DataFrame(scraped_data, columns=["A", "B", "C"])
0 голосов
/ 11 ноября 2018

Я исследовал проблему и попробовал несколько фрагментов на своем ноутбуке.

Проблема не в DataFrame , так как вы читаете каждую строку за раз в цикле, проблема в URL, ваша программа правильно удаляет страницу, содержащую таблицу, и выдает ошибка для почтового индекса, который не имеет элемента.

Рассмотрим первый тест:

Я создал HTML-страницу без таблицы:

 <html>
  <head>
     <title>Demo page</title>
  </head>

  <body>
     <h2>Demo without table</h2>
  </body>
</html>

А потом я выполнил код на python, как показано ниже:

from bs4 import BeautifulSoup
data = open('table.html').read()
parser = BeautifulSoup(data, 'html.parser')
table = parser.find('table')
rows = table.find_all('tr')
print(rows)

Вышеупомянутый код остановлен из-за исключение NoneType , поскольку parser.find () возвращает объект NoneType , если элемент таблицы не найден в данных html. Так что find_all () не является методом объекта NoneType, поэтому выдает ошибку.

Итак, я изменил свой HTML-код, как показано ниже:

<html>
<head>
    <title>Demo page</title>
</head>

<body>
    <h2>Demo without table</h2>
    <table>
        <tr>Demo</tr>
    </table>
</body>
</html>

Теперь код Python работает без каких-либо исключений, так как присутствует элемент таблицы.

Итак, вывод:

Исключением является то, что один из почтовых индексов в кадре данных приводит к URL-адресу, который не содержит таблицы. Итак, я рекомендую вам внести небольшое изменение в ваш код:

scraped_data = []

for x, row in postcodes_for_urls.iterrows():
  page = requests.get("http://myurl"+(row['postcode_URL']))
  soup = BeautifulSoup(page.content, 'html.parser')
  table = soup.find('table')
  #add this :
  if table == None :
      continue

  table_rows = table.find_all('tr')
  for tr in table_rows:
    td = tr.find_all('td')
    row = [tr.text for tr in td]
    scraped_data.append(row)

pd.DataFrame (scraped_data, columns = ["A", "B", "C"])

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