Очистить таблицу через итерацию только после загрузки данных с задержкой, используя Python? - PullRequest
0 голосов
/ 24 июня 2018

Я пытаюсь очистить данные, используя python (библиотеки Requests и BeautifulSoup4 вместе с Selenium)

Когда я пытался извлечь некоторые данные с веб-сайта, где данные загружаются после некоторой задержки, он возвращает пустое значение.Я понимаю, что для этой задачи мне нужно использовать WebDriverWait.

import requests
from bs4 import BeautifulSoup
# selenium imports
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutException

# Initialize a Chrome webdriver
driver = webdriver.Chrome()

# Grab the web page
driver.get("http://")

# use selenium.webdriver.support.ui.Select
# that we imported above to grab the Select element called 
# lmStatType, then select the first value

# We will use .find_element_by_name here because we know the name
dropdown = Select(driver.find_element_by_name("lmStatType"))
dropdown.select_by_value("1")

# select the year 2560
dropdown = Select(driver.find_element_by_name("lmYear"))
dropdown.select_by_value("60")

# Now we can grab the search button and click it
search_button = driver.find_elements_by_xpath("//*[contains(text(), 'ตกลง')]"[0]
search_button.click()

# we just look at .page_source of the driver
driver.page_source

# We can feed that into Beautiful Soup
doc = BeautifulSoup(driver.page_source, "html.parser")

# It's a tricky table, also tried with class names
rows = doc.find('table', id='datatable')
print(rows) # returns empty

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

Кроме того, просто попытался получить данные об уровне района отдельно, например (но не могу определить точный класс / идентификатор)

url = 'http://'
res = requests.get(url)
soup = BeautifulSoup(res.text,"lxml")
for tr in soup.find(class_="display").find_all("tr"):
    data = [item.get_text(strip=True) for item in tr.find_all(["th","td"])]
    print(data)

Любая помощьоценили.Заранее спасибо.Приношу свои извинения, если это дублирующий вопрос.

1 Ответ

0 голосов
/ 25 июня 2018

Как я уже говорил в комментарии, html фактически дает вам конечную точку, где он получает эти данные. С этого момента довольно просто получать данные с помощью запросов.

В вашем html-формате говорится: "sAjaxSource": "../datasource/showStatProvince.php?statType=1&year=60". Это конечная точка, которую использует сайт. Так что вам просто нужно вернуться на один уровень назад в структуру url-сайтов и использовать вместо нее "/ datasource / ...."

Взгляните:

import requests
from bs4 import BeautifulSoup
import re

url = "http://stat.bora.dopa.go.th/stat/statnew/statTDD/datasource/showStatDistrict.php?statType=1&year=60&rcode=10"

r = requests.get(url)
# endpoint returns json
data = r.json()
aaData = data['aaData']

# this base url for viewing the details for each hit
view_url = "http://stat.bora.dopa.go.th/stat/statnew/statTDD/views/showZoneData.php"

# the first line in the dataset is actually html
# we convert this to plain text
html_header = aaData[0]
html_header_stripped = [BeautifulSoup(e, "html.parser").get_text() for e in html_header]

# and the insert this html_header_stripped in the aaData-list
aaData[0] = html_header_stripped
for rcode, region_html,male,female, total, home in aaData:
    # first element is "<font color='red'><b>กรุงเทพมหานคร</b></font>"
    # secound is "<a href=javascript:openWindow('?rcode=1001&statType=1&year=60')>ท้องถิ่นเขตพระนคร</a>"
    # we need to extract the link that opens in new window to be able to iterate further
    soup = BeautifulSoup(region_html, "html.parser")
    region = soup.get_text()
    try:
        link_element = soup.find('a').get('href')
        rel_link = re.search("\('(.+)'\)", link_element).group(1)
        abs_link = view_url + rel_link
    except:
        abs_link = None

    print("{};{};{};{};{};{};{}".format(rcode, region, abs_link,male,female,total,home))

Здесь я печатаю результаты, но, скажем, вы хотите перейти по ссылкам и получить эти данные, вы можете сохранить результаты в списке диктовок и впоследствии выполнить итерации или сделать это внутри цикла for.

...