Mon but de télécharger un fichier zip de https: // www .shareinvestor.com / Prix / prix_download_zip_file.zip? Type = History_all & Market = Bursa
C'est un lien dans cette page Web https://www.shareinvestor.com/ Prix / prix_download.html # /? Type = Prix_download_all_stocks_bursa . Ensuite, enregistrez-le dans ce répertoire Le code exécuté jusqu'à la fin avec Aucune erreur mais elle ne télécharge pas.
Le fichier zip est automatiquement strud> téléchargé quand cliquez sur https : //www.shareinvestor.com/prices/price_download_zip_file.zip? Type = History_all & Market = Bursa manuellement. P> Mon code avec un nom d'utilisateur et un mot de passe de travail est utilisé. Le nom d'utilisateur HTML Snippet: strong> "/ home / vinvin / shklse / code> (J'utilise Pythonaywherewhere). Puis décompressez-le et l'extrait de fichier CSV dans le répertoire.
<li><a href="/prices/price_download_zip_file.zip?type=history_all&market=bursa">All Historical Data</a> <span>About 220 MB</span></li>
5 Réponses :
La raison est due à la page Web du chargement lentement. J'ai ajouté une attente de 20 secondes après ouvrir la page Web Link
#!/usr/bin/python print "hello from python 2" import urllib2 from selenium import webdriver from selenium.webdriver.common.keys import Keys import time from pyvirtualdisplay import Display import requests, zipfile, os display = Display(visible=0, size=(800, 600)) display.start() profile = webdriver.FirefoxProfile() profile.set_preference('browser.download.folderList', 2) profile.set_preference('browser.download.manager.showWhenStarting', False) profile.set_preference('browser.download.dir', "/home/vinvin/shKLSE/") # application/zip not /zip profile.set_preference('browser.helperApps.neverAsk.saveToDisk', 'application/zip') for retry in range(5): try: browser = webdriver.Firefox(profile) print "firefox" break except: time.sleep(3) time.sleep(1) browser.get("https://www.shareinvestor.com/my") time.sleep(10) login_main = browser.find_element_by_xpath("//*[@href='/user/login.html']").click() print browser.current_url username = browser.find_element_by_id("sic_login_header_username") password = browser.find_element_by_id("sic_login_header_password") print "find id done" username.send_keys("bkcollection") password.send_keys("123456") print "log in done" login_attempt = browser.find_element_by_xpath("//*[@type='submit']") login_attempt.submit() browser.get("https://www.shareinvestor.com/prices/price_download.html#/?type=price_download_all_stocks_bursa") print browser.current_url time.sleep(20) dl = browser.find_element_by_xpath("//*[@href='/prices/price_download_zip_file.zip?type=history_all&market=bursa']").click() time.sleep(30) browser.close() browser.quit() display.stop() zip_ref = zipfile.ZipFile('/home/vinvin/shKLSE/file.zip', 'r') zip_ref.extractall('/home/vinvin/shKLSE') zip_ref.close() # remove with correct path os.remove('/home/vinvin/shKLSE/file.zip')
Merci, ça fonctionne bien avec votre code, avec de petits modifications
Prenez le côté de la portée du sélénium. Changez les paramètres de préférence afin que lorsque le lien soit cliqué sur cliqué (première vérification si le lien est valide), il vous donne une pop up demandant d'enregistrer, utilisez maintenant sikuli http://www.sikuli.org/ Pour cliquer sur la fenêtre contextuelle. Les types MIME ne fonctionnent pas toujours et il n'y a pas de réponse noire et blanche pourquoi elle ne fonctionne pas. p>
Comme mentionné, pas de pop-up. Vous essayez de pouvoir manuellement avec le nom d'utilisateur et le mot de passe.
Je n'ai pas essayé sur le site que vous avez mentionné, cependant suivant le code fonctionne parfaitement et télécharge le zip. Si vous ne pouvez pas télécharger le zip, le type MIME pourrait être différent. Vous pouvez utiliser le navigateur chromé et l'inspection réseau pour vérifier le type MIME STROR> du fichier que vous essayez de télécharger.
J'ai réécrit votre script, avec des commentaires expliquant pourquoi j'ai apporté les modifications que j'ai faites. Je pense que votre principal problème pourrait avoir été un mauvais mimeType, cependant, votre script avait un journal de problèmes systémiques qui l'auraient rendu plus fiable au mieux. Cette réécriture utilise des attentes explicites, qui supprime complètement la nécessité d'utiliser Vous allez Nécessité de faire ce qui suit pour vous assurer que tous les modules sont installés: p> temps.sleep () code>, ce qui lui permet de fonctionner aussi vite que possible, tout en éliminant les erreurs résultant de la congestion du réseau.
Demandes d'installation PIP Explicit SELENIUM Réessayez PyvirtualDisplay Code> P>
#!/usr/bin/python
from __future__ import print_function # Makes your code portable
import os
import glob
import zipfile
from contextlib import contextmanager
import requests
from retry import retry
from explicit import waiter, XPATH, ID
from selenium import webdriver
from pyvirtualdisplay import Display
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.wait import WebDriverWait
DOWNLOAD_DIR = "/tmp/shKLSE/"
def build_profile():
profile = webdriver.FirefoxProfile()
profile.set_preference('browser.download.folderList', 2)
profile.set_preference('browser.download.manager.showWhenStarting', False)
profile.set_preference('browser.download.dir', DOWNLOAD_DIR)
# I think your `/zip` mime type was incorrect. This works for me
profile.set_preference('browser.helperApps.neverAsk.saveToDisk',
'application/vnd.ms-excel,application/zip')
return profile
# Retry is an elegant way to retry the browser creation
# Though you should narrow the scope to whatever the actual exception is you are
# retrying on
@retry(Exception, tries=5, delay=3)
@contextmanager # This turns get_browser into a context manager
def get_browser():
# Use a context manager with Display, so it will be closed even if an
# exception is thrown
profile = build_profile()
with Display(visible=0, size=(800, 600)):
browser = webdriver.Firefox(profile)
print("firefox")
try:
yield browser
finally:
# Let a try/finally block manage closing the browser, even if an
# exception is called
browser.quit()
def main():
print("hello from python 2")
with get_browser() as browser:
browser.get("https://www.shareinvestor.com/my")
# Click the login button
# waiter is a helper function that makes it easy to use explicit waits
# with it you dont need to use time.sleep() calls at all
login_xpath = '//*/div[@class="sic_logIn-bg"]/a'
waiter.find_element(browser, login_xpath, XPATH).click()
print(browser.current_url)
# Log in
username = "bkcollection"
username_id = "sic_login_header_username"
password = "123456"
password_id = "sic_login_header_password"
waiter.find_write(browser, username_id, username, by=ID)
waiter.find_write(browser, password_id, password, by=ID, send_enter=True)
# Wait for login process to finish by locating an element only found
# after logging in, like the Logged In Nav
nav_id = 'sic_loggedInNav'
waiter.find_element(browser, nav_id, ID)
print("log in done")
# Load the target page
target_url = ("https://www.shareinvestor.com/prices/price_download.html#/?"
"type=price_download_all_stocks_bursa")
browser.get(target_url)
print(browser.current_url)
# CLick download button
all_data_xpath = ("//*[@href='/prices/price_download_zip_file.zip?"
"type=history_all&market=bursa']")
waiter.find_element(browser, all_data_xpath, XPATH).click()
# This is a bit challenging: You need to wait until the download is complete
# This file is 220 MB, it takes a while to complete. This method waits until
# there is at least one file in the dir, then waits until there are no
# filenames that end in `.part`
# Note that is is problematic if there is already a file in the target dir. I
# suggest looking into using the tempdir module to create a unique, temporary
# directory for downloading every time you run your script
print("Waiting for download to complete")
at_least_1 = lambda x: len(x("{0}/*.zip*".format(DOWNLOAD_DIR))) > 0
WebDriverWait(glob.glob, 300).until(at_least_1)
no_parts = lambda x: len(x("{0}/*.part".format(DOWNLOAD_DIR))) == 0
WebDriverWait(glob.glob, 300).until(no_parts)
print("Download Done")
# Now do whatever it is you need to do with the zip file
# zip_ref = zipfile.ZipFile(DOWNLOAD_DIR, 'r')
# zip_ref.extractall(DOWNLOAD_DIR)
# zip_ref.close()
# os.remove(zip_ref)
print("Done!")
if __name__ == "__main__":
main()
Pouvez-vous expliquer @retry (exception, essais = 5, délai = 3) code> et
@ContextManager code>? Y a-t-il un autre module commun qui peut utiliser pour remplacer
réessayer code> et
explicite code>? Pythonanywhere n'a pas ces deux modules.
@BkCollection, avant de mettre à jour ma réponse, pouvez-vous d'abord me dire si vous pouvez l'utiliser pour installer des dépendances externes? Spécifiquement, réessayer code> et
explicite code>?
https://help.pythonyanywhere.com/pages/installingnewmodules/ code>
Cela fonctionne bien fondamentalement. Mais il est normalement bloqué après Imprimer "Firefox" CODE> ET BESOIN DE RECHERCHER à nouveau. Ça arrive comme 2 fois sur trois
Plus de détails L'explication sera meilleure pour les débutants
Je ne vois aucun inconvénient majeur dans votre bloc de code comme tel. Mais voici quelques recommandations via cette solution et l'exécution de ce script de test automatisé:
AJAX appels CODE> sont en jeu et la gestion de ceux-ci sont au-delà de la portée de cette question. LI>
- Vous pouvez envisager de vérifier le répertoire de téléchargement recherché d'abord et si non disponible, en créer un nouveau. Ce bloc de code de cette fonctionnalité est sous Windows Style et fonctionne parfaitement sur la plate-forme Windows. LI>
- Une fois que vous avez cliqué sur "Connexion", induisez quelque chose
attendre code> pour le DOM HTML pour rendant correctement. LI>
- Lorsque vous souhaitez découvrir le processus de téléchargement, vous devez définir certaines plus de préférences dans le
firefoxprofile code> comme mentionné dans mon code ci-dessous. Li>
- Toujours envisager de maximiser la fenêtre du navigateur via
Browser.maximze_window () Code> Li>
- Lorsque vous commencez à télécharger, vous devez attendre suffisamment de temps pour obtenir le fichier complètement téléchargé. LI>
- Si vous utilisez
Browser.Quit () code> à la fin, vous n'avez pas besoin d'utiliser navigateur.close () code> li>
- Vous pouvez envisager de remplacer tous les
temps.sleep () code> avec l'un des implicitlywait code> ou explicitwait code> ou fluentwait code >. li>
-
Voici votre propre bloc de code avec quelques modifications simples dedans: P>
#!/usr/bin/python
print "hello from python 2"
import urllib2
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from pyvirtualdisplay import Display
import requests, zipfile, os
display = Display(visible=0, size=(800, 600))
display.start()
newpath = 'C:\\home\\vivvin\\shKLSE'
if not os.path.exists(newpath):
os.makedirs(newpath)
profile = webdriver.FirefoxProfile()
profile.set_preference("browser.download.dir",newpath);
profile.set_preference("browser.download.folderList",2);
profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/zip");
profile.set_preference("browser.download.manager.showWhenStarting",False);
profile.set_preference("browser.helperApps.neverAsk.openFile","application/zip");
profile.set_preference("browser.helperApps.alwaysAsk.force", False);
profile.set_preference("browser.download.manager.useWindow", False);
profile.set_preference("browser.download.manager.focusWhenStarting", False);
profile.set_preference("browser.helperApps.neverAsk.openFile", "");
profile.set_preference("browser.download.manager.alertOnEXEOpen", False);
profile.set_preference("browser.download.manager.showAlertOnComplete", False);
profile.set_preference("browser.download.manager.closeWhenDone", True);
profile.set_preference("pdfjs.disabled", True);
for retry in range(5):
try:
browser = webdriver.Firefox(profile)
print "firefox"
break
except:
time.sleep(3)
time.sleep(1)
browser.maximize_window()
browser.get("https://www.shareinvestor.com/my")
time.sleep(10)
login_main = browser.find_element_by_xpath("//*[@href='/user/login.html']").click()
time.sleep(10)
print browser.current_url
username = browser.find_element_by_id("sic_login_header_username")
password = browser.find_element_by_id("sic_login_header_password")
print "find id done"
username.send_keys("bkcollection")
password.send_keys("123456")
print "log in done"
login_attempt = browser.find_element_by_xpath("//*[@type='submit']")
login_attempt.submit()
browser.get("https://www.shareinvestor.com/prices/price_download.html#/?type=price_download_all_stocks_bursa")
print browser.current_url
time.sleep(20)
dl = browser.find_element_by_xpath("//*[@href='/prices/price_download_zip_file.zip?type=history_all&market=bursa']").click()
time.sleep(900)
browser.close()
browser.quit()
display.stop()
zip_ref = zipfile.ZipFile(/home/vinvin/sh/KLSE, 'r')
zip_ref.extractall(/home/vinvin/sh/KLSE)
zip_ref.close()
os.remove(zip_ref)
Merci. Comment suggérez-vous de remplacer le implicitlywait code> ou
explicitwait code> ou
fluentwait. Code>? Assurez-vous qu'il est téléchargé avant que procéda est la meilleure idée.
@bkCollection Vous pouvez induire implicitlywait code> une fois au début de votre script afin que le sélénium attend de manière cohérente. Vous pouvez également utiliser
explicitwait code> pour que certains éléments soient visibles / cliquables dans le DOM HTML. Sinon, vous pouvez utiliser
fluestwait code> pour accélérer votre exécution par interrogation fréquente, ignorer les exceptions. Pour
Assurez-vous qu'il est téléchargé avant que procéda code> Vous pouvez envisager d'utiliser
urllib.request.urlreTrieve code> module qui bloquera jusqu'à ce que le téléchargement soit effectué. Merci
Pourriez-vous modifier la réponse. Je sais que temps.sleep code> est une mauvaise idée. Merci
@BkCollection c'est tout votre propre code. Je viens d'ajouter les modifications minimales nécessaires pour faire fonctionner votre code de code :) merci
Pourriez-vous le rendre meilleur pour la partie de téléchargement, pour vous assurer qu'il est complètement téléchargé avant de décompresser le fichier? Merci beaucoup
@Debanjanb ça a fonctionné pour moi. Mais existe-t-il un moyen de renommer le fichier téléchargé?
@ ABHI1610 Pouvez-vous soulever une nouvelle question selon votre nouvelle exigence s'il vous plaît? Mais je suppose qu'il existe une QA / discussion existante sur ce sujet. S'il vous plaît vérifier une fois.
Était curieux de savoir si une solution sur la plate-forme Windows peut être acceptable pour vous? Merci
@Dev c'est acceptable. Tant que cela peut fonctionner de manière cohérente.
Observé que vous avez utilisé code> dolderlist code>,
showwhenStarting code>,
télécharger.dir code> &
jetkask.savetodidisk code> dans votre code mais vous avez havn 't mentionné à leur sujet dans la description. Avez-vous des exigences en fonction de ces fonctionnalités? Merci
Non, tant qu'il est téléchargé dans le répertoire dans Zip et le décompressez-le.