Nom*_*hir 13 html python parsing web-scraping pandas
我正在尝试从“ https://www.wunderground.com/personal-weather-station/dashboard?ID=KMAHADLE7#history/tdata/s20170201/e20170201/mcustom.html ”天气地下页面中删除历史天气数据。我有以下代码:
import pandas as pd
page_link = 'https://www.wunderground.com/personal-weather-station/dashboard?ID=KMAHADLE7#history/tdata/s20170201/e20170201/mcustom.html'
df = pd.read_html(page_link)
print(df)
Run Code Online (Sandbox Code Playgroud)
我有以下回应:
Traceback (most recent call last):
File "weather_station_scrapping.py", line 11, in <module>
result = pd.read_html(page_link)
File "/anaconda3/lib/python3.6/site-packages/pandas/io/html.py", line 987, in read_html
displayed_only=displayed_only)
File "/anaconda3/lib/python3.6/site-packages/pandas/io/html.py", line 815, in _parse raise_with_traceback(retained)
File "/anaconda3/lib/python3.6/site-packages/pandas/compat/__init__.py", line 403, in raise_with_traceback
raise exc.with_traceback(traceback)
ValueError: No tables found
Run Code Online (Sandbox Code Playgroud)
虽然这个页面显然有一个表格,但它没有被 read_html 选择。我尝试过使用 Selenium,以便可以在阅读之前加载页面。
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
driver.get("https://www.wunderground.com/personal-weather-station/dashboard?ID=KMAHADLE7#history/tdata/s20170201/e20170201/mcustom.html")
elem = driver.find_element_by_id("history_table")
head = elem.find_element_by_tag_name('thead')
body = elem.find_element_by_tag_name('tbody')
list_rows = []
for items in body.find_element_by_tag_name('tr'):
list_cells = []
for item in items.find_elements_by_tag_name('td'):
list_cells.append(item.text)
list_rows.append(list_cells)
driver.close()
Run Code Online (Sandbox Code Playgroud)
现在的问题是它找不到“tr”。我将不胜感激任何建议。
G. *_*son 15
这是使用 selenium 进行浏览器自动化的解决方案
\n\nfrom selenium import webdriver\nimport pandas as pd\ndriver = webdriver.Chrome(chromedriver)\ndriver.implicitly_wait(30)\n\ndriver.get(\'https://www.wunderground.com/personal-weather-station/dashboard?ID=KMAHADLE7#history/tdata/s20170201/e20170201/mcustom.html\')\n df=pd.read_html(driver.find_element_by_id("history_table").get_attribute(\'outerHTML\'))[0]\n\nTime Temperature Dew Point Humidity Wind Speed Gust Pressure Precip. Rate. Precip. Accum. UV Solar\n0 12:02 AM 25.5 \xc2\xb0C 18.7 \xc2\xb0C 75 % East 0 kph 0 kph 29.3 hPa 0 mm 0 mm 0 0 w/m\xc2\xb2\n1 12:07 AM 25.5 \xc2\xb0C 19 \xc2\xb0C 76 % East 0 kph 0 kph 29.31 hPa 0 mm 0 mm 0 0 w/m\xc2\xb2\n2 12:12 AM 25.5 \xc2\xb0C 19 \xc2\xb0C 76 % East 0 kph 0 kph 29.31 hPa 0 mm 0 mm 0 0 w/m\xc2\xb2\n3 12:17 AM 25.5 \xc2\xb0C 18.7 \xc2\xb0C 75 % East 0 kph 0 kph 29.3 hPa 0 mm 0 mm 0 0 w/m\xc2\xb2\n4 12:22 AM 25.5 \xc2\xb0C 18.7 \xc2\xb0C 75 % East 0 kph 0 kph 29.3 hPa 0 mm 0 mm 0 0 w/m\xc2\xb2\nRun Code Online (Sandbox Code Playgroud)\n\n编辑并细分到底发生了什么,因为上面的一行实际上不是很好的自记录代码:
\n\n设置驱动程序后,我们选择具有 ID 值的表(幸运的是,该站点实际上使用了合理且描述性的 ID)
\n\ntab=driver.find_element_by_id("history_table")\nRun Code Online (Sandbox Code Playgroud)\n\n然后,从该元素中,我们获取 HTML 而不是 Web 驱动程序元素对象
\n\ntab_html=tab.get_attribute(\'outerHTML\')\nRun Code Online (Sandbox Code Playgroud)\n\n我们使用pandas来解析html
\n\ntab_dfs=pd.read_html(tab_html)\nRun Code Online (Sandbox Code Playgroud)\n\n来自文档:
\n\n\n\n\n“read_html 返回 DataFrame 对象的列表,即使 HTML 内容中仅包含\n单个表”
\n
因此,我们使用我们拥有的唯一表(索引为零)对该列表进行索引
\n\ndf=tab_dfs[0]\nRun Code Online (Sandbox Code Playgroud)\n
您可以使用requests并避免打开浏览器。
您可以使用以下方式获取当前条件:
'jQuery1720724027235122559_1542743885014('并从左侧和')'右侧剥离。然后处理json字符串。
您可以通过以下方式调用 API 来获取摘要和历史记录
然后,您需要'jQuery1720724027235122559_1542743885015('从前面和');'右侧剥离。然后您就有了一个可以解析的 JSON 字符串。
JSON 示例:

您可以通过在浏览器中使用 F12 开发工具并检查页面加载期间创建的流量的网络选项卡来找到这些 URL。
的一个示例,注意到JSON 中current似乎存在问题,因此我将其替换为:nulls"placeholder"
import requests
import pandas as pd
import json
from pandas.io.json import json_normalize
from bs4 import BeautifulSoup
url = 'https://stationdata.wunderground.com/cgi-bin/stationlookup?station=KMAHADLE7&units=both&v=2.0&format=json&callback=jQuery1720724027235122559_1542743885014&_=15'
res = requests.get(url)
soup = BeautifulSoup(res.content, "lxml")
s = soup.select('html')[0].text.strip('jQuery1720724027235122559_1542743885014(').strip(')')
s = s.replace('null','"placeholder"')
data= json.loads(s)
data = json_normalize(data)
df = pd.DataFrame(data)
print(df)
Run Code Online (Sandbox Code Playgroud)