【问题标题】:PhantomJS returning empty web page (python, Selenium)PhantomJS 返回空网页(python,Selenium)
【发布时间】:2015-06-10 09:33:03
【问题描述】:

尝试屏幕抓取网站,而无需在 python 脚本中启动实际的浏览器实例(使用 Selenium)。我可以用 Chrome 或 Firefox 做到这一点——我已经尝试过了,它可以工作——但我想使用 PhantomJS,所以它是无头的。

代码如下所示:

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 选项时,它工作正常。我想也许该网站正在返回基于用户代理的垃圾,所以我试着假装它。没有区别。

我错过了什么?

更新:我会尽量保持下面的 sn-p 更新,直到它工作。下面是我目前正在尝试的。

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.

【问题讨论】:

    标签: python selenium selenium-webdriver phantomjs


    【解决方案1】:

    我遇到了同样的问题,没有多少代码可以让驱动程序等待。
    问题在于 https 网站上的 SSL 加密,忽略它们就可以解决问题。

    调用 PhantomJS 驱动为:

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

    这解决了我的问题。

    【讨论】:

    • 这对我有用,与'--ssl-protocol=TLSv1' 部分的其他答案不同。你知道为什么这会导致它工作吗?
    • 我今天也遇到了这个问题。我的页面停止工作并返回 ssl-protocol=TLSv1 解决了它。惊人的发现。
    【解决方案2】:

    您需要等待页面加载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 秒,让带有 class="content"div 元素可见,然后再获取页面源。


    此外,您可能需要忽略 SSL 错误

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

    不过,我很确定这与 PhantomJS 中的重定向问题有关。 phantomjsbugtracker 中有一张未公开的票:

    【讨论】:

    • 好的,我会尝试一下....但是如果“获取”命令在返回之前不等待“页面加载”完成,它会有多大用处?似乎应该内置。是否可以使用非定时等待命令,等待“页面加载”事件(或任何它被称为)?
    • @cbp2 不,selenium 不会等待未完成的异步请求或浏览器中的异步代码执行。使用显式等待应该可以解决问题。
    • 我们接近了,但仍然没有雪茄。我添加了等待,但等待一个 ID 出现 - 超时,虽然我知道 ID 应该在那里。代码输出和屏幕截图仍然是空的。 Traceback (most recent call last): File "scrape_CS.py", line 35, in &lt;module&gt; element = wait.until(EC.element_to_be_clickable((By.ID,'loginField'))) File "/Users/carey/anaconda/lib/python2.7/site-packages/selenium/webdriver/support/wait.py", line 75, in until raise TimeoutException(message, screen, stacktrace) TimeoutException: Message: Screenshot: available via screen
    • @cbp2 好的,感谢您试用。我已经更新了答案,请检查。
    • 不幸的是,结果相同。顺便说一句,我需要所有“dcap”的东西吗?如果没有,我会删除它。你能解释一下为什么你认为 ignore-ssl-errors 是问题所在吗?我确实在 Chrome 中看到了关于此的警告,但它仍然有效。它在 PhantomJS 中不起作用。
    【解决方案3】:

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

    这对我有用

    【讨论】:

      猜你喜欢
      • 2015-11-18
      • 2014-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-28
      • 2020-10-07
      相关资源
      最近更新 更多