webentwicklung-frage-antwort-db.com.de

PhantomJS, das leere Webseite zurückgibt (Python, Selenium)

Beim Versuch, eine Website mit einem Scrape-Screening zu testen, ohne eine tatsächliche Browserinstanz in einem Python-Skript (mit Selenium) starten zu müssen. Ich kann das mit Chrome oder Firefox machen - ich habe es ausprobiert und es funktioniert - aber ich möchte PhantomJS verwenden, damit es headless ist.

Der Code sieht so aus:

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()

Die Ausgabe ist lediglich:

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

Wenn ich jedoch die Chrome- oder Firefox-Optionen verwende, funktioniert das einwandfrei. Ich dachte, vielleicht würde die Website auf der Basis des Benutzeragenten Junk zurückgeben, also versuchte ich, das herauszufinden. Kein Unterschied.

Was vermisse ich?

AKTUALISIERT: Ich werde versuchen, das untenstehende Snippet so lange auf dem neuesten Stand zu halten, bis es funktioniert. Was ich unten versuche, versuche ich gerade.

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.
18
cbp2

Ich war mit dem gleichen Problem konfrontiert und es gab keine Menge Code, um den Treiber warten zu lassen.
.__ Das Problem ist die SSL-Verschlüsselung auf den https-Websites.

Rufen Sie den PhantomJS-Treiber als:

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

Dies hat das Problem für mich gelöst.

29
Raunaq Kochar

Sie müssen warten, bis die Seite geöffnet ist d. Normalerweise geschieht dies mit einem Explicit Wait to wait, bis ein Schlüsselelement auf einer Seite vorhanden oder sichtbar ist. Zum Beispiel:

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
# ...

Hier warten wir bis zu 10 Sekunden, bis ein div-Element mit class="content" sichtbar wird, bevor die Seitenquelle abgerufen wird.


Darüber hinaus müssen Sie möglicherweise SSL-Fehler ignorieren:

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

Ich bin mir ziemlich sicher, dass dies mit den Umleitungsproblemen in PhantomJS zusammenhängt. In phantomjs bugtracker gibt es ein offenes Ticket:

3
alecxe

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

Das hat bei mir funktioniert

0
Arjun Lal