Невозможно очистить данные таблицы с помощью BeautifulSoup с веб-сайта

#python #html #web-scraping #html-table #beautifulsoup

#python #HTML #очистка веб-страниц #html-таблица #beautifulsoup

Вопрос:

Я следую онлайн-уроку (https://www.analyticsvidhya.com/blog/2015/10/beginner-guide-web-scraping-beautiful-soup-python /) для веб-очистки HTML-таблицы. Когда я следовал руководству, я смог очистить данные таблицы, но я, когда попытался очистить данные из этого (https://www.masslottery.com/games/lottery/search/results-history.html?game_id=15amp;mode=2amp;selected_date=2019-03-04amp;x=12amp;y=11 ) веб-сайт, на котором я не смог этого сделать.

Я пытался использовать scrapy раньше, но получил те же результаты.

Вот код, который я использовал.

 import urllib.request

wiki = "https://www.masslottery.com/games/lottery/search/results-history.html?game_id=15amp;mode=2amp;selected_date=2019-03-04amp;x=12amp;y=11"
page = urllib.request.urlopen(wiki)
from bs4 import BeautifulSoup
soup = BeautifulSoup(page, "lxml")


all_tables=soup.find_all('table')


right_table=soup.find('table', class_='zebra-body-only')
print(right_table)
  

Это то, что я получаю, когда запускаю этот код на терминале

 <table cellspacing="0" class="zebra-body-only">
<tbody id="target-area">
</tbody>
</table>
  

Хотя, когда я просматриваю веб-сайт массовой лотереи с помощью Google Chrome, это то, что я вижу

 <table cellspacing="0" class="zebra-body-only"                                  <tbody id="target-area">
<tr class="odd">
<th>Draw #</th>
<th>Draw Date</th>
<th>Winning Number</th>
<th>Bonus</th>
</tr>
<tr><td>2107238</td>
<td>03/04/2019</td>
<td>01-04-05-16-23-24-27-32-34-41-42-44-47-49-52-55-63-65-67-78</td><td>No Bonus</td>
</tr>
<tr class="odd">
<td>2107239</td>
<td>03/04/2019</td>
<td>04-05-11-15-19-20-23-24-25-28-41-45-52-63-64-68-71-72-73-76</td><td>4x</td>
</tr> 
....(And so on)
  

Я хочу иметь возможность извлекать данные из этой таблицы.

Ответ №1:

Это происходит потому, что веб-сайт выполняет другой вызов для загрузки результатов. Начальная ссылка загружает только страницу, но не результаты. Используя инструменты разработчика Chrome для проверки запросов, вы сможете найти запрос, который вам нужно повторить, чтобы получить результаты.

Это означает, что для получения результатов вы можете просто вызвать запрос, упомянутый выше, и вообще не вызывать веб-страницу.

К счастью, конечная точка, которую вы должны вызвать, уже находится в удобном формате JSON.

GET https://www.masslottery.com/data/json/search/dailygames/history/15/201903.json?_=1555083561238

Где я предполагаю 1555083561238 , это временная метка.

Комментарии:

1. И как мне вызвать эту конечную точку? Извините, я действительно новичок в этом.

2. поскольку это запрос GET, просто замените вашу переменную «wiki» на этот URL-адрес. Возможно, вы захотите взглянуть на пакет запросов python, поскольку он более подробный для вызова различных URL-адресов с помощью разных методов (GET, PUT, POST и т. Д.)

Ответ №2:

Страница динамическая, поэтому она отображается после выполнения запроса. Вы можете либо а) использовать решение с помощью JC1 и получить доступ к ответу json. Или вы можете использовать Seleneium для имитации открытия браузера, рендеринга страницы, а затем захвата таблицы:

 from bs4 import BeautifulSoup
from selenium import webdriver


url = 'https://www.masslottery.com/games/lottery/search/results-history.html?game_id=15amp;mode=2amp;selected_date=2019-03-04amp;x=12amp;y=11'  

driver = webdriver.Chrome()
driver.get(url)
page = driver.page_source

soup = BeautifulSoup(page, "lxml")

all_tables=soup.find_all('table')


right_table=soup.find('table', class_='zebra-body-only')
  

Также в качестве примечания: обычно, если я вижу <table> теги, я позволяю Pandas выполнять работу за меня (обратите внимание, мне заблокирован доступ к сайту, поэтому я не могу их протестировать):

 import pandas as pd
from selenium import webdriver


url = 'https://www.masslottery.com/games/lottery/search/results-history.html?game_id=15amp;mode=2amp;selected_date=2019-03-04amp;x=12amp;y=11'  

driver = webdriver.Chrome()
driver.get(url)
page = driver.page_source

# will return a list of dataframes
tables = pd.read_html(page)

# chose the dataframe you want from the list by it's position
df = tables[0]
  

Ответ №3:

да, я бы сохранил полученные вами данные в файле, чтобы посмотреть, действительно ли там то, что вы ищете. с помощью open(‘stuff.html ‘,’w’) как f: f.write(ответ.текст)

unicode, попробуйте: импортировать кодеки codecs.open(fp,’w’,’utf-8′) как f:

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

простой способ — использовать selenium убедитесь, что вы ждете, пока то, что вы ищете, не появится на странице (это динамично)