Ошибка «NoneType» из-за изменения в HTML. В. Как вы помогаете менять форматы данных? - PullRequest
0 голосов
/ 19 апреля 2020

Я получаю сообщение об ошибке ниже HTML, которое дает мне ошибку (пропущенные данные между ними). Я хочу удалить данные только после сильного тега, поэтому ХОРОШО, 1: 56: 5 и 1: 56,5

<td><strong>Track Rating:</strong> GOOD</td>
<td></td>
<td><strong>Gross Time:</strong> 1:56:5</td>
<td><strong>Mile Rate:</strong> 1:56:5</td>

HTML, который работает отлично (без отсутствующих данных)

<td><strong>Track Rating:</strong> GOOD</td>
<td><strong>Gross Time:</strong> 2:29:6</td>
<td><strong>Mile Rate:</strong> 1:58:6</td>
<td><strong>Lead Time:</strong> 30.3</td>

Мой код для удаления этих данных:

from datetime import datetime, date, timedelta
import requests
import re
import csv
import os
import numpy
import pandas as pd
from bs4 import BeautifulSoup as bs

base_url = "http://www.harness.org.au/racing/results/?firstDate="
base1_url = "http://www.harness.org.au"

webpage_response = requests.get('http://www.harness.org.au/racing/results/?firstDate=')

soup = bs(webpage_response.content, "html.parser")

format = "%d-%m-%y"
delta = timedelta(days=1)
yesterday = datetime.today() - timedelta(days=1)


enddate = datetime(2019, 1, 1)



while enddate <= yesterday:
    enddate += timedelta(days=1)
    enddate1 = enddate.strftime("%d-%m-%y") 
    new_url = base_url + str(enddate1)
    soup12 = requests.get(new_url)
    soup1 = bs(soup12.content, "html.parser") 
    table1 = soup1.find('table', class_='meetingListFull')

    tr = table1.find_all('tr', {'class':['odd', 'even']})

    for tr1 in tr or trr:
        tr2 = tr1.find('a').get_text()
        tr3 = tr1.find('a')['href']
        newurl = base1_url + tr3
        with requests.Session() as s:
            webpage_response = s.get(newurl)
            soup = bs(webpage_response.content, "html.parser")
            #soup1 = soup.select('.content')
            results = soup.find_all('div', {'class':'forPrint'})
....
for race in results:
tableoftimes = race.find('table', class_='raceTimes')
trackrating = tableoftimes.find(text="Track Rating:").findPrevious('td').contents[1]
grosstime = tableoftimes.find(text="Track Rating:").find_next('td').contents[1]
milerate = tableoftimes.find(text="Gross Time:").findNext('td').contents[1]
leadtime = tableoftimes.find(text="Mile Rate:").findNext('td').contents[1]
firstquarter = tableoftimes.find(text="Lead Time:").findNext('td').contents[1]
....

Там, где точки просто добавляются в список для использования данных

Моя цель - позже добавьте в список, чтобы получить все данные. В лучшем случае я хочу получить данные, даже если они завершены, но я полностью застрял там, где я бы даже создал правило, чтобы просто игнорировать все данные, если они неполные. Попробовал несколько вещей, таких как следующий сосед, но я постоянно получаю сообщение о том, что объект NoneType не имеет атрибута «findNext» из-за изменения данных на веб-сайте.

Обновление Я обновил код до

tableoftimes = race.find('table', class_='raceTimes')
                for row in tableoftimes.find_all('tr'):
                    string23 = [td.get_text() for td in row.find_all('td')]

Что печатает ['Рейтинг трека: ХОРОШО ', 'Время брутто: 2: 05: 1 ', 'Миля Оценить: 1: 56: 4 ',' Время исполнения: 8.1 '] [' Первый квартал: 29.4 ',' Второй квартал: 32 ',' Третий квартал: 28.4 ',' Четвертый квартал: 27.2 '] [' Поля: HFHD x HFNK ']

Я хочу данные курсивом, но только если он соответствует заголовку. Большинство операторов if, которые я пытаюсь выдать, выдают ошибку - у объекта 'list' нет атрибута 'string' или чего-то подобного, так как я пытаюсь найти текст во вложенном списке. Есть идеи отсюда?

Ответы [ 2 ]

1 голос
/ 19 апреля 2020

Вы можете добавить None-safety с парой вложенных if, но было бы очень грязно, если бы вам пришлось добавить if для каждой находки, которая потенциально может вернуть None. Попробуйте этот подход: { ссылка }

for row in table.find_all("tr")[1:]:
    datarow = [td.get_text() for td in row.find_all("td")]
0 голосов
/ 20 апреля 2020

Другое решение.

from simplified_scrapy import SimplifiedDoc,req,utils
html = '''
<table class="meetingListFull">
<td><strong>Track Rating:</strong> GOOD</td>
<td><strong>Gross Time:</strong> 2:29:6</td>
<td><strong>Mile Rate:</strong> 1:58:6</td>
<td><strong>Lead Time:</strong> 30.3</td>
</table>
'''
doc = SimplifiedDoc(html)
table1 = doc.select('table.meetingListFull')
strongs = table1.selects('strong')
print([(s.text,s.nextText()) for s in strongs])

Результат:

[('Track Rating:', 'GOOD'), ('Gross Time:', '2:29:6'), ('Mile Rate:', '1:58:6'), ('Lead Time:', '30.3')]

Вот еще несколько примеров. https://github.com/yiyedata/simplified-scrapy-demo/tree/master/doc_examples

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