【问题标题】:Issues designing a simple web scraper in Python在 Python 中设计一个简单的网络爬虫的问题
【发布时间】:2018-03-04 13:19:19
【问题描述】:

我遵循了一个在线教程,并成功创建了一个与一步一步操作相同的网络爬虫。

但是,当尝试在我想要的网站上实现此代码时,我的控制台上返回的只是空白数据。我希望有人可以查看我为收集数据而放下的短代码,看看我是否正确地完成了这项工作,或者我是否不知道网站上的某些协议不允许从中刮取数据。

# import libraries
from urllib.request import urlopen as uReq
from bs4 import BeautifulSoup as soup 

myurl = "http://smartgriddashboard.eirgrid.com/#all/generation"

# opening up connection, grabbing the page
uClient = uReq(myurl)
page_html = uClient.read()
uClient.close()

# html parsing
page_soup = soup(page_html, "html.parser")

# find the data of interest
key_stats = page_soup.findAll("div",{"class":"key-stats-container"})

当我尝试调用 key_stats 时,出现的只是 []。正如我之前所说,在在线教程的示例网页上执行此操作时,该类中的所有数据都已存储。

我不是专业的程序员,所有这一切对我来说都是很新的,所以任何和所有的帮助都将不胜感激。

【问题讨论】:

  • 该页面的内容(您试图抓取)正在动态更新。所以,选择任何浏览器模拟器,如selenium 来解析它们。

标签: python html web-scraping


【解决方案1】:

问题是您尝试从页面中抓取的 div 是使用 Javascript 动态生成的。它不在HTML source code 中,这意味着urllib.request 无权访问该信息。当您在浏览器中加载页面时,您应该注意到该信息不会立即显示在屏幕上,而是在页面加载几秒钟后显示统计信息。

您可以尝试查看网站的 Javascript 或源文件,并尝试使用 find where the information is coming from(通常是 JSON 或 XML 文件),或使用 selenium(自动浏览器)之类的东西来解析之后的页面页面上有相关元素:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()

try:
    driver.get("http://smartgriddashboard.eirgrid.com/#all/generation") # load the page
    WebDriverWait(driver, 15).until(EC.presence_of_element_located((By.CSS_SELECTOR, '.key-stats-container > .stat-box'))) # wait till relevant elements are on the page
except:
    driver.quit() # quit if there was an error getting the page or we've waited 15 seconds and the stats haven't appeared.
stat_elements = driver.find_elements_by_css_selector('.key-stats-container > .stat-box')
for el in stat_elements: 
    print(el.find_element_by_css_selector('label').text)
    print(el.find_element_by_css_selector('p').text)
driver.quit()                                      

WebDriverWait(driver, 15).until(EC.presence_of_element_located((By.CSS_SELECTOR, '.key-stats-container > .stat-box'))) 将等待 15 秒或until 在超时之前通过 css 选择器找到一个元素,您可以根据需要更改 15 秒。

我不只是等待.key-stats-container,而是等待.key-stats-container > .stat-box(具有stats-box 类的元素,它是.key-stats-container 的直接子元素),因为有一个点.key-stats-container 已加载但统计数据没有:

   <span class="load"></span>
    <div class="error-msg">
        <p>We had some trouble gathering the data.</p>
        <p>Refresh to try again.</p>
    </div>
</div>

这是输出:

LATEST SYSTEM
GENERATION
4,885 MW
THERMAL GENERATION
(COAL, GAS, OTHER)
56.81 %
RENEWABLE
GENERATION
43.03 %
NET
IMPORT
0.16 %

【讨论】:

  • 完美,尝试启动和运行 chrome 驱动程序有点混乱,但现在完美无缺,非常感谢
【解决方案2】:

看起来整个页面都没有被下载。您可以通过print(page_soup.prettify()) 进行检查。

解决此问题的方法是使用Selenium 打开网络浏览器,然后下载页面:

from selenium import webdriver
from bs4 import BeautifulSoup as soup
driver = webdriver.Firefox(profile)
driver.get('http://smartgriddashboard.eirgrid.com/#all/generation')
page_soup = soup(driver.page_source, 'html.parser')
  • 请注意,Selenium 需要安装 geckodriver
  • 我确信有更好的方法,使用Requests 或其他方式。
  • 一个超级简单的方法是通过右键单击网络浏览器获取页面源,然后让 Beautiful Soup 使用它。

附带说明,虽然它有效,但您的 findAll 似乎是旧方法。 new methodCSS selectors 可能更好。

【讨论】:

  • 这不起作用,因为统计信息会在 driver.get 完成后几秒钟加载(请参阅我的答案)。
  • 也许 - 它对我有用,但同意你的答案更好。
猜你喜欢
  • 1970-01-01
  • 2017-01-26
  • 2016-06-23
  • 2015-06-26
  • 2011-08-15
  • 2023-03-13
  • 2021-12-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多