So laden Sie eine Datei mit Python, Selen und PhantomJS herunter

Hier ist meine Situation: Ich muss mich bei einer Website anmelden und eine CSV von dort herunterladen, kopflos von einem Linux-Server. Die Seite benutzt JS und funktioniert nicht ohne sie.

Nach einigen Recherchen ging ich mit Selen und PhantomJS. Logging, Einstellung der Parameter für die CSV und die Suche nach dem Download-Button mit Selen / PhantomJS / Py3 war kein Problem, eigentlich überraschend angenehm.

Aber das Klicken auf den Download-Button hat nichts getan. Nach einigen Recherchen habe ich herausgefunden, dass PhantomJS nicht scheint, Download-Dialoge und Downloads zu unterstützen, sondern dass es auf der kommenden Feature-Liste ist.

Also ich dachte, ich benutze einen Workaround mit urllib nachdem ich herausgefunden habe, dass der Download-Button gerade einen REST API Url anruft. Problem ist, es funktioniert nur, wenn du in der Seite angemeldet bist. Also der erste Versuch scheiterte, als er zurückkehrte: b'{"success":false,"session":"expired"}' was Sinn macht, wie ich erwarte, dass Selen und Urllib verschiedene Sessions verwenden. Also ich dachte, ich benutze die Header von Seleniums Fahrer in urrlib versuchen, dies:

 ... url = 'http://www.foo.com/api/index' data = urllib.parse.urlencode({ 'foopara': 'cadbrabar', }).encode('utf-8') headers = {} for cookie in driver.get_cookies(): headers[cookie['name']] = cookie['value'] req = urllib.request.Request(url, data, headers) with urllib.request.urlopen(req) as response: page = response.read() driver.close() 

Leider ergab sich das gleiche Ergebnis einer abgelaufenen Sitzung. Bin ich etwas falsch gemacht, gibt es einen Weg um dieses, andere Vorschläge oder bin ich in einer Sackgasse? Danke im Voraus.

4 Solutions collect form web for “So laden Sie eine Datei mit Python, Selen und PhantomJS herunter”

Ich habe eine Lösung gefunden und wollte es teilen. Eine Anforderung hat sich geändert, ich verwende PhantomJS nicht mehr, sondern der chromedriver der kopflos mit einem virtuellen Framebuffer arbeitet. Gleiches Ergebnis und es wird die Arbeit erledigt.


Was Sie brauchen, ist:

pip install selenium pyvirtualdisplay

apt-get install xvfb

ChromeDriver herunterladen


Ich benutze Py3.5 und eine Testdatei von ovh.net mit einem Tag anstelle einer Schaltfläche. Das Skript wartet darauf, dass das auf der Seite vorhanden ist und dann darauf klickt. Wenn Sie nicht auf das Element warten und auf einer asynchronen Website sind, ist das Element, das Sie versuchen zu klicken, vielleicht noch nicht da. Der Download-Speicherort ist ein Ordner relativ zum Scriptsort. Das Skript prüft dieses Verzeichnis, wenn die Datei bereits mit einer zweiten Verzögerung heruntergeladen wird. Wenn ich nicht falsche Dateien sein sollte .part während des Downloads und sobald es die .dat ist, die im filename das Skript beendet. Wenn Sie den virtuellen Framebuffer und den Treiber schließen, bevor der Download nicht abgeschlossen ist. Das komplette Skript sieht so aus:

 # !/usr/bin/python # coding: utf-8 import os import sys import time from pyvirtualdisplay import Display from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By import glob def main(argv): url = 'http://ovh.net/files' dl_dir = 'downloads' filename = '1Mio.dat' display = Display(visible=0, size=(800, 600)) display.start() chrome_options = webdriver.ChromeOptions() dl_location = os.path.join(os.getcwd(), dl_dir) prefs = {"download.default_directory": dl_location} chrome_options.add_experimental_option("prefs", prefs) chromedriver = "./chromedriver" driver = webdriver.Chrome(executable_path=chromedriver, chrome_options=chrome_options) driver.set_window_size(800, 600) driver.get(url) WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.XPATH, '//a[@href="' + filename + '"]'))) hyperlink = driver.find_element_by_xpath('//a[@href="' + filename + '"]') hyperlink.click() while not(glob.glob(os.path.join(dl_location, filename))): time.sleep(1) driver.close() display.stop() if __name__ == '__main__': main(sys.argv) 

Ich hoffe das hilft jemand in der Zukunft.

Wenn die Schaltfläche, die Sie herunterladen möchten, die Dateiverknüpfung hat, können Sie das Herunterladen mit Python-Code testen, da PhantonJs keinen Download selbst unterstützt. Also, wenn Ihr Download-Button nicht die Datei-Link, können Sie nicht testen.

Um mit datei link und phyton zu testen (um zu behaupten, dass Datei existiert) können Sie dieses Thema verfolgen. Wie ich bin ein C # -Entwickler und Hoden, ich weiß nicht, die bessere Möglichkeit, den Code in Python ohne Fehler zu schreiben, aber Im sicher können Sie:

Grundlegende http-Datei herunterladen und speichern auf Festplatte in Python?

Ich habe vor kurzem Selen verwendet, um ChromeDriver zu nutzen, um eine Datei aus dem Internet herunterzuladen. Dies funktioniert, weil Chrome automatisch die Datei herunterlädt und sie in der Downloads-Datei für Sie speichert. Das war einfacher als mit PhantomJS.

Ich empfehle, mit ChromeDriver mit Selen zu suchen und diese Route zu gehen: https://github.com/SeleniumHQ/selenium/wiki/ChromeDriver

EDIT – Wie unten dargelegt, vernachlässigte ich darauf, wie man ChromeDriver einrichtet, um im kopflosen Modus zu laufen. Hier ist mehr Infos: http://www.chrisle.me/2013/08/running-headless-selenium-with-chrome/

Oder: https://gist.github.com/chuckbutler/8030755

Du kannst so etwas probieren:

 from requests.auth import HTTPBasicAuth import requests url = "http://some_site/files?file=file.csv" # URL used to download file # GET-request to get file content using your web-site's credentials to access file r = requests.get(url, auth=HTTPBasicAuth("your_username", "your_password")) # Saving response content to file on your computer with open("path/to/folder/to/save/file/filename.csv", 'w') as my_file: my_file.write(r.content) 
Python ist die beste Programmiersprache der Welt.