使用 lxml 抓取动态 html 字段
Scraping dynamic html fields with lxml
我一直在尝试使用 lxml
抓取 HTML 页面的动态字段
代码非常简单,如下所示:
from lxml import html
import requests
page = requests.get('http://www.airmilescalculator.com/distance/blr-to-cdg/')
tree = html.fromstring(page.content)
miles = tree.xpath('//input[@class="distanceinput2"]/text()')
print miles
我导出的结果只是一个空列表[]
结果预计是列表中的一个数字。
但是我能够抓取同一页面的静态字段。
在此先感谢您的帮助。
您不能 select 来自 input
字段的文本节点,因为没有文本节点。
<input type="text" class="distanceinput2" .. />
要从 input
字段中获取 value
,请使用:
miles = [node.value for node in tree.xpath('//input[@class="distanceinput2"]')]
你应该得到它们。
所需的值已计算出来,因此我们需要访问该页面并模拟一个 Click
来获取它们。splinter
包就是为此而制作的。
from pyvirtualdisplay import Display
display = Display(visible=0)
display.start()
from splinter import Browser
url = 'http://www.airmilescalculator.com/distance/blr-to-cdg/'
browser = Browser()
browser.visit(url)
browser.find_by_id('haemulti')[0].click()
print browser.find_by_id('totaldistancemiles')[0].value
print browser.find_by_id('totaldistancekm')[0].value
print browser.find_by_id('nauticalmiles')[0].value
browser.quit()
display.stop()
pyvirtualdisplay
用于隐藏浏览器。
输出:
$python test.py
4868
7834
4230
这里的问题是文本框中的值是由 javascript 添加的。当页面加载时,文本字段中的值为 0。因此,即使您抓取,您也不会获得该值,因为抓取的内容会得到这个
<input class="distanceinput2" id="totaldistancemiles" name="totaldistancemiles" readonly="readonly" size="5" title="Distance in miles" type="text" value="0"/>
<input class="distanceinput2" id="totaldistancekm" name="totaldistancekm" readonly="readonly" size="5" title="Distance in kilometers" type="text" value="0"/>
<input class="distanceinput2" id="nauticalmiles" name="nauticalmiles" readonly="readonly" size="5" title="Distance in nautical miles" type="text" value="0"/>
所以,如果你想得到网站上的价值,是不可能通过抓取的。
您可以试试 phantom JS,它就像一个无头浏览器。还没有试验过,但看起来有机会。这里有一个 link 可以提供帮助。
希望对您有所帮助!
如您所知,距离是根据对 Google 地图 API 的 XHR 调用结果动态计算的。 simulate/repeat 仅使用 requests
并不容易,因为您至少需要一个真实浏览器具有的 Javascript 引擎。
这里是你如何通过selenium
and headless PhantomJS
browser解决它:
from selenium import webdriver
driver = webdriver.PhantomJS()
driver.get("http://www.airmilescalculator.com/distance/blr-to-cdg/")
distance = driver.find_element_by_id("totaldistancemilestext").text
print(distance)
打印 4868
.
我一直在尝试使用 lxml
抓取 HTML 页面的动态字段
代码非常简单,如下所示:
from lxml import html
import requests
page = requests.get('http://www.airmilescalculator.com/distance/blr-to-cdg/')
tree = html.fromstring(page.content)
miles = tree.xpath('//input[@class="distanceinput2"]/text()')
print miles
我导出的结果只是一个空列表[]
结果预计是列表中的一个数字。
但是我能够抓取同一页面的静态字段。
在此先感谢您的帮助。
您不能 select 来自 input
字段的文本节点,因为没有文本节点。
<input type="text" class="distanceinput2" .. />
要从 input
字段中获取 value
,请使用:
miles = [node.value for node in tree.xpath('//input[@class="distanceinput2"]')]
你应该得到它们。
所需的值已计算出来,因此我们需要访问该页面并模拟一个 Click
来获取它们。splinter
包就是为此而制作的。
from pyvirtualdisplay import Display
display = Display(visible=0)
display.start()
from splinter import Browser
url = 'http://www.airmilescalculator.com/distance/blr-to-cdg/'
browser = Browser()
browser.visit(url)
browser.find_by_id('haemulti')[0].click()
print browser.find_by_id('totaldistancemiles')[0].value
print browser.find_by_id('totaldistancekm')[0].value
print browser.find_by_id('nauticalmiles')[0].value
browser.quit()
display.stop()
pyvirtualdisplay
用于隐藏浏览器。
输出:
$python test.py
4868
7834
4230
这里的问题是文本框中的值是由 javascript 添加的。当页面加载时,文本字段中的值为 0。因此,即使您抓取,您也不会获得该值,因为抓取的内容会得到这个
<input class="distanceinput2" id="totaldistancemiles" name="totaldistancemiles" readonly="readonly" size="5" title="Distance in miles" type="text" value="0"/>
<input class="distanceinput2" id="totaldistancekm" name="totaldistancekm" readonly="readonly" size="5" title="Distance in kilometers" type="text" value="0"/>
<input class="distanceinput2" id="nauticalmiles" name="nauticalmiles" readonly="readonly" size="5" title="Distance in nautical miles" type="text" value="0"/>
所以,如果你想得到网站上的价值,是不可能通过抓取的。
您可以试试 phantom JS,它就像一个无头浏览器。还没有试验过,但看起来有机会。这里有一个 link 可以提供帮助。
希望对您有所帮助!
如您所知,距离是根据对 Google 地图 API 的 XHR 调用结果动态计算的。 simulate/repeat 仅使用 requests
并不容易,因为您至少需要一个真实浏览器具有的 Javascript 引擎。
这里是你如何通过selenium
and headless PhantomJS
browser解决它:
from selenium import webdriver
driver = webdriver.PhantomJS()
driver.get("http://www.airmilescalculator.com/distance/blr-to-cdg/")
distance = driver.find_element_by_id("totaldistancemilestext").text
print(distance)
打印 4868
.