使用Python编程以编程方式打开一个页面

3

你能从这个网页中提取VIN码吗?

我尝试了urllib2.build_opener、requests和mechanize。我也提供了用户代理,但它们都无法看到VIN码。

opener = urllib2.build_opener()
opener.addheaders = [('User-agent',('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_7) ' 'AppleWebKit/535.1 (KHTML, like Gecko) ' 'Chrome/13.0.782.13 Safari/535.1'))]
page = opener.open(link)
soup = BeautifulSoup(page)

table = soup.find('dd', attrs = {'class': 'tip_vehicleStats'})
vin = table.contents[0]
print vin

你得到什么?整个页面吗? - aIKid
我得到了一个空的span类,但实际上VIN号码应该在那里。当您在浏览器中检查元素时,您可以看到它。 - Teodor Scorpan
@TeodorScorpan 这是使用Javascript动态创建的。 - Ramchandra Apte
你是说我不能放弃它吗? - Teodor Scorpan
一个测试某个东西是否可以正常抓取的好方法是在浏览器中关闭 JavaScript 并查看它。 - halfer
4个回答

7

那个页面大部分信息都是通过Javascript(可能是通过Ajax调用)加载和显示的,很可能是为了直接防止被抓取。因此,要爬取这个网站,你需要使用能运行Javascript并远程控制它的浏览器,或者用Javascript编写抓取程序,或者你需要拆解该网站并找出它如何加载Javascript以及如何加载它们,并尝试复制这些调用。


非常感谢Lennart Regebro。听起来实现起来很困难。=) - Teodor Scorpan
嘿 @TeodorScorpan,我肯定不想用JavaScript来实现一个爬虫。:-) 但是,如果你调试JavaScript代码,可能会发现这些实际调用只是简单的Ajax调用。我认为,这是你最好的选择。 - Lennart Regebro
你有没有任何示例或教程展示如何“解构网站并复制这些调用”?我一直在想这个问题,但从未看到过任何真正的成功案例。 - B.Mr.W.
@B.Mr.W. 不,你只需要调试网站上的Javascript并查看正在进行的Ajax调用,然后尝试复制它们即可。 - Lennart Regebro

5
您可以使用浏览器自动化工具来实现此目的。
例如,这个简单的Selenium脚本就可以完成您的工作。
from selenium import webdriver
from bs4 import BeautifulSoup

link = "https://www.iaai.com/Vehicles/VehicleDetails.aspx?auctionID=14712591&itemID=15775059&RowNumber=0"
browser = webdriver.Firefox()
browser.get(link)
page = browser.page_source

soup = BeautifulSoup(page)

table = soup.find('dd', attrs = {'class': 'tip_vehicleStats'})
vin = table.contents.span.contents[0]
print vin

顺便提一下,table.contents[0]输出整个span,包括span标签。

table.contents.span.contents[0]仅输出VIN号码。


2
您可以使用Selenium,它调用浏览器。这对我很有效:
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.keys import Keys
import time

# See: https://dev59.com/EnnZa4cB1Zd3GeqPsaCV
browser = webdriver.Firefox() # Get local session of firefox
browser.get("https://www.iaai.com/Vehicles/VehicleDetails.aspx?auctionID=14712591&itemID=15775059&RowNumber=0") # Load page


time.sleep(0.5) # Let the page load


# Search for a tag "span" with an attribute "id" which contains "ctl00_ContentPlaceHolder1_VINc_VINLabel"
e=browser.find_element_by_xpath("//span[contains(@id,'ctl00_ContentPlaceHolder1_VINc_VINLabel')]")
e.text
# Works for me : u'4JGBF7BE9BA648275'

browser.close()

我和shshank同时发布了这个帖子。基本上,我们的想法是一样的:使用selenium。 - Charles JOUBERT

-1

您不必使用Selenium。 只需进行额外的get请求:

import requests

stock_number = '123456789'        # located at VEHICLE INFORMATION  
url = 'https://www.clearvin.com/ads/iaai/check?stockNumber={}&vin='.format(stock_number)
vin = requests.get(url).json()['car']['vin']

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接