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.
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.
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:
driver = webdriver.PhantomJS (service_args = ['- ignore-ssl-errors = true', '--ssl-protocol = TLSv1'])
Das hat bei mir funktioniert