没有html标签时的HTML Scraping

时间:2018-02-19 22:45:21

标签: python python-3.x selenium web-scraping beautifulsoup

我正在尝试从此website获取高程数据,以及开始和结束传递时间。 到目前为止,我已经查看了源代码并且无法使用Beautiful Soup来获得我想要的东西,因为源代码没有任何关于我感兴趣的信息的标签。该信息包含在函数中,名称为spStart ,这是相应的论点。我开始使用selenium来获取Javascript处理的代码,但我最终获得了与页面上的源代码相同的内容,现在我被卡住了。

这是我尝试使用selenium:

import datetime
import time
from bs4 import BeautifulSoup
import re
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import selenium.webdriver.chrome.service as service
from lxml import html


try:
    #Launching chrome in headless mode to access inspect element code''
    service = service.Service('/correct_path/chromedriver.exe')
    chrome_options = Options()  
    chrome_options.add_argument("--headless")
    chrome_options.add_argument("--disable-gpu")
    driver = webdriver.Chrome(chrome_options=chrome_options, executable_path=r'/correct_path/chromedriver.exe')  
    driver.get("https://www.n2yo.com/passes/?s=39090&a=1") 
    print("Chrome Browser Initialized in Headless Mode")


    soup = BeautifulSoup(driver.execute_script("return document.documentElement.innerHTML;"), "lxml")
    print(soup)



except KeyboardInterrupt:
    driver.quit()
    print("Driver Exited")

当我运行此代码时,它为我提供了在chrome中使用“view source”选项时看到的html。我的印象是,通过使用selenium以这种方式获取源代码,我会看到在chrome中的同一页面上使用“inspect element”选项时可用的内容。

有人会介意解释我出错的地方并建议一种可行的方法来获取我想要的数据,可能还有一个解释的例子吗?我真的很感激。

感谢您的时间。

2 个答案:

答案 0 :(得分:3)

不是不一样,Inspect Element检查DOM,源页面虽然实际上是DOM的原始种子页面,DOM可以动态更改,通常由JS代码更改,  有时非常戏剧化。您还会注意到Inspect Element显示了源不显示的阴影元素。

要了解差异的显着程度,请访问chrome://settings/并点击Inspect element,然后查看View page source并进行比较。

您应该在加载后定位元素,然后通过arguments[0]而不是整个页面document

html_of_interest=driver.execute_script('return arguments[0].innerHTML',element)
sel_soup=BeautifulSoup(html_of_interest, 'lxml')

这有两个实际案例:

1

元素尚未加载到DOM中,您需要等待元素:

browser.get("url")
sleep(experimental) # usually get will finish only after the page is loaded but sometimes there is some JS woo running after on load time

try:
    element= WebDriverWait(browser, delay).until(EC.presence_of_element_located((By.ID, 'your_id_of_interest')))
    print "element is ready do the thing!"
    html_of_interest=driver.execute_script('return arguments[0].innerHTML',element)
    sel_soup=BeautifulSoup(html_of_interest, 'html.parser')
except TimeoutException:
    print "Somethings wrong!"   

2

元素在阴影根中,你需要首先扩展阴影根,可能不是你的情况,但我会在这里提到它,因为它与将来的参考相关。例如:

import selenium
from selenium import webdriver
driver = webdriver.Chrome()
from bs4 import BeautifulSoup


def expand_shadow_element(element):
  shadow_root = driver.execute_script('return arguments[0].shadowRoot', element)
  return shadow_root

driver.get("chrome://settings")
root1 = driver.find_element_by_tag_name('settings-ui')

html_of_interest=driver.execute_script('return arguments[0].innerHTML',root1)
sel_soup=BeautifulSoup(html_of_interest, 'html.parser')
sel_soup# empty root not expande

shadow_root1 = expand_shadow_element(root1)

html_of_interest=driver.execute_script('return arguments[0].innerHTML',shadow_root1)
sel_soup=BeautifulSoup(html_of_interest, 'html.parser')
sel_soup

enter image description here

答案 1 :(得分:2)

我不知道您感兴趣的页面中有哪些数据。但是,如果您使用的表格数据,则下面的脚本值得尝试:

from selenium.webdriver import Chrome
from contextlib import closing
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup

URL = "https://www.n2yo.com/passes/?s=39090&a=1"

chrome_options = Options()  
chrome_options.add_argument("--headless")

with closing(Chrome(chrome_options=chrome_options)) as driver:
    driver.get(URL)
    soup = BeautifulSoup(driver.page_source, 'lxml')
    for items in soup.select("#passestable tr"):
        data = [item.text for item in items.select("th,td")]
        print(data)

部分输出:

['Start ', 'Max altitude', 'End ', 'All passes']
['Date, Local time', 'Az', 'Local time', 'Az', 'El', 'Local time', 'Mag ', 'Info']
['20-Feb 19:17', 'N13°', '19:25', 'E76°', '81°', '19:32', 'S191°', '-', 'Map and details']
['21-Feb 06:24', 'SSE151°', '06:31', 'E79°', '43°', '06:38', 'N358°', '-', 'Map and details']