2015-04-05 103 views
18

試圖屏幕刮一個網站,而不必在python腳本(使用Selenium)啓動一個實際的瀏覽器實例。我可以使用Chrome或Firefox來做到這一點 - 我已經嘗試過並且能夠正常工作 - 但我想使用PhantomJS,因此它是無頭的。PhantomJS返回空網頁(python,Selenium)

的代碼看起來是這樣的:

import sys 
import traceback 
import time 

from selenium import webdriver 
from selenium.webdriver.common.keys import Keys 
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities 

dcap = dict(DesiredCapabilities.PHANTOMJS) 
dcap["phantomjs.page.settings.userAgent"] = (
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/53 " 
    "(KHTML, like Gecko) Chrome/15.0.87" 
) 

try: 
    # Choose our browser 
    browser = webdriver.PhantomJS(desired_capabilities=dcap) 
    #browser = webdriver.PhantomJS() 
    #browser = webdriver.Firefox() 
    #browser = webdriver.Chrome(executable_path="/usr/local/bin/chromedriver") 

    # Go to the login page 
    browser.get("https://www.whatever.com") 

    # For debug, see what we got back 
    html_source = browser.page_source 
    with open('out.html', 'w') as f: 
     f.write(html_source) 

    # PROCESS THE PAGE (code removed) 

except Exception, e: 
    browser.save_screenshot('screenshot.png') 
    traceback.print_exc(file=sys.stdout) 

finally: 
    browser.close() 

輸出僅僅是:

<html><head></head><body></body></html> 

但是,當我使用Chrome或Firefox瀏覽器的選項,它工作正常。我想也許該網站是基於用戶代理返回垃圾,所以我試圖僞造。沒有不同。

我錯過了什麼?

更新:我會盡量保持下面的代碼片段更新,直到它工作。以下是我目前正在嘗試的內容。

import sys 
import traceback 
import time 
import re 

from selenium import webdriver 
from selenium.webdriver.support.wait import WebDriverWait 
from selenium.webdriver.common.by import By 
from selenium.webdriver.common.keys import Keys 
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities 
from selenium.webdriver.support import expected_conditions as EC 

dcap = dict(DesiredCapabilities.PHANTOMJS) 
dcap["phantomjs.page.settings.userAgent"] = (
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/53 (KHTML, like Gecko) Chrome/15.0.87") 

try: 
    # Set up our browser 
    browser = webdriver.PhantomJS(desired_capabilities=dcap, service_args=['--ignore-ssl-errors=true']) 
    #browser = webdriver.Chrome(executable_path="/usr/local/bin/chromedriver") 

    # Go to the login page 
    print "getting web page..." 
    browser.get("https://www.website.com") 

    # Need to wait for the page to load 
    timeout = 10 
    print "waiting %s seconds..." % timeout 
    wait = WebDriverWait(browser, timeout) 
    element = wait.until(EC.element_to_be_clickable((By.ID,'the_id'))) 
    print "done waiting. Response:" 

    # Rest of code snipped. Fails as "wait" above. 

回答

3

您需要等待頁面LOA d。通常,它通過使用Explicit Wait等待關鍵元素存在或在頁面上可見。例如:

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


# ... 
browser.get("https://www.whatever.com") 

wait = WebDriverWait(driver, 10) 
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.content"))) 

html_source = browser.page_source 
# ... 

在這裏,我們將等待長達10秒div元素與class="content"獲取頁面源之前變得可見。


此外,您可能需要忽略SSL錯誤

browser = webdriver.PhantomJS(desired_capabilities=dcap, service_args=['--ignore-ssl-errors=true']) 

雖然,我敢肯定這是在PhantomJS有關重定向的問題。有一個開放式票phantomjs錯誤追蹤系統:

+0

好的,我會給出一個嘗試....但如果它不等待「頁面加載」完成返回前,「get」命令是多麼有用?似乎應該是內置的。是否有一個可以使用的非定時等待命令,等待「頁面加載」事件(或任何它被稱爲)? – cbp2 2015-04-06 13:13:57

+0

@ cbp2 nope,selenium不會等待瀏覽器中出色的異步請求或異步代碼執行。使用明確的等待應該可以解決問題。 – alecxe 2015-04-06 13:16:31

+0

我們正在接近,但仍然沒有雪茄。我添加了等待,但等待一個ID出席 - 超時,但我知道ID應該在那裏。代碼輸出和截圖仍然是空的。 '回溯(最近最後調用): 文件 「scrape_CS.py」,第35行,在 元素= wait.until(EC.element_to_be_clickable((By.ID, 'loginField'))) 文件「/用戶/ carey/anaconda/lib/python2.7/site-packages/selenium/webdriver/support/wait.py「,第75行,直到 raise TimeoutException(消息,屏幕,堆棧跟蹤) TimeoutException:消息: 屏幕截圖:通過屏幕可用# – cbp2 2015-04-06 14:40:15

25

我面臨同樣的問題,沒有任何的代碼量,以使駕駛員等待正在幫助。
問題是在https網站上的SSL加密,忽略它們會做伎倆。

調用PhantomJS驅動程序:

driver = webdriver.PhantomJS(service_args=['--ignore-ssl-errors=true', '--ssl-protocol=TLSv1']) 

這解決了這個問題對我來說。

+0

這對我有用,區別在於''--ssl-protocol = TLSv1''部分的其他答案。你知道爲什麼這導致它的工作? – rwolst 2016-05-03 17:40:41

+1

我今天也遇到了這個問題。我的頁面停止工作並正在返回 ssl-protocol = TLSv1解決了它。驚人的發現。 – 2016-10-24 19:42:51

+1

@ meoww-哈哈哈,很高興它的工作! – 2016-10-24 21:02:10