我一直在尝试使用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
我得出的结果只是一个空列表[]
预计结果将是列表中的数字。
但是我能够抓取同一页面的静态字段。
提前感谢您的帮助。
答案 0 :(得分:3)
您无法从input
字段中选择文本节点,因为没有文本节点。
<input type="text" class="distanceinput2" .. />
要从value
字段中获取input
,请使用:
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
答案 1 :(得分:2)
这里的问题是文本框中的值是通过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"/>
所以,如果你想获得网站上的价值,就不可能通过抓取来实现。
你可以试试幻影JS,它就像一个无头浏览器。 Haven没有尝试过,但看起来有机会。这是link,可以提供帮助。
希望有所帮助!
答案 2 :(得分:2)
正如您已经发现的那样,距离是根据对Google Maps API的XHR调用结果动态计算出来的。仅使用requests
进行模拟/重复并不容易,因为您至少需要一个真正的浏览器具有的Javascript引擎。
以下是通过selenium
和无头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
。