【问题标题】:Web Scraping with Python BS使用 Python BS 进行网页抓取
【发布时间】:2021-04-14 12:28:50
【问题描述】:

试图从 Weather Underground 中抓取一些天气数据。在获取日期/日期、高/低温度和预报(即“部分多云”)之前,我获取感兴趣的数据没有任何困难。每个都在一个没有类的 div 中。每个的父级是一个 class="obs-date" 的 div(见下图)

[WxUn HTML 图像][1]

以下尝试的代码已注释掉其他选项。每个都返回一个空列表。

def get_wx(city, state):
    city=city.lower()
    state=state.lower()
    
    # get current conditions; 'weather' in url
    current_dict = get_current(city, state)

    # get forecast; 'forecast' in url
    f_url = f'https://www.wunderground.com/forecast/us/{state}/{city}'
    f_response = req.get(f_url)
    f_soup = BeautifulSoup(f_response.text, 'html.parser')
    cast_dates = f_soup.find_all('div', class_="obs-date")
    # cast_dates = f_soup.find_all('div', attrs={"class":"obs-date"})
    # cast_dates = f_soup.select('div.obs-date')
    print(cast_dates)
    
get_wx("Portland", "ME")

对我所缺少的任何帮助表示感谢。

【问题讨论】:

  • 请以您正在使用的 html 文档的文本形式分享一个 minimal 示例。
  • OpenWeatherMap 使用其API 将天气作为 JSON 数据提供,这要简单得多。
  • 也许获取所有 divs 并使用 Python 中的索引来获得预期的 div - all_divs[0], all_divs[1],
  • 问题可能是:页面使用JavaScript 向HTML 添加元素,但BeautifulSoup 无法运行JavaScript。它可能需要使用Selenium来控制可以运行JavaScript的真实网络浏览器。
  • 您可以随时嵌套find/find_all。您可以使用 cast_dates[0].find_all(...) 仅在第一个 cast_dates 内部搜索 - 您可以使用 for-loop 对所有元素重复它。 for item in cast_dates: item.find_all(...)

标签: python beautifulsoup


【解决方案1】:

据我所知,您尝试解析的整个块是由 javascript 驱动的,这就是您使用 beautifulsoup 得到空结果的原因

ADDITIONAL CONDITIONS 部分可以使用bs4 以及以下所有内容完全解析。最后的表格可以使用pandas解析。

要抓取 javascript 内容,您可以使用 requests-htmlselenium 库。

from requests_html import HTMLSession
import json

session = HTMLSession()
url = "https://www.wunderground.com/weather/us/me/portland"
response = session.get(url)
response.html.render(sleep=1)

data = []

current_date = response.html.find('.timestamp strong', first = True).text
weather_conditions = response.html.find('.condition-icon p', first = True).text
gusts = response.html.find('.medium-uncentered span', first = True).text
current_temp = response.html.find('.current-temp .is-degree-visible', first = True).text

data.append({
    "Last update": current_date,
    "Current weather": weather_conditions,
    "Temperature": current_temp,
    "Gusts": gusts,
})

print(json.dumps(data, indent = 2, ensure_ascii = False))

输出:

[
  {
    "Last update": "1:27 PM EDT on April 14, 2021",
    "Current weather": "Fair",
    "Temperature": "49 F",
    "Gusts": "13 mph"
  }
]

【讨论】:

    猜你喜欢
    • 2011-10-21
    • 1970-01-01
    • 2020-10-04
    • 2021-05-08
    • 2018-07-20
    • 2021-01-13
    • 2020-03-13
    • 2016-02-10
    相关资源
    最近更新 更多