ваше описание довольно запутанно; прямая конкатенация десятичных значений не кажется полезной в большинстве контекстов. следующий код будет прикладывать каждую букву к 8-битовому символу, а THEN - конкатенацию. так работает стандартная кодировка ASCII
def ASCII(s):
x = 0
for i in xrange(len(s)):
x += ord(s[i])*2**(8 * (len(s) - i - 1))
return x
Я переписал ваш сценарий с комментариями, объясняющими, почему я внес изменения, которые я сделал. Я думаю, что ваша главная проблема могла быть плохим миметиком, однако ваш сценарий имел журнал системных проблем, которые сделали бы его в лучшем случае ненадежным. В этом переписании используются явные ожидания, что полностью устраняет необходимость использования time.sleep()
, позволяя ему работать как можно быстрее, а также устранять ошибки, возникающие из-за перегрузки сети.
Вам понадобится сделать следующее: убедитесь, что все модули установлены:
pip install requests explicit selenium retry pyvirtualdisplay
Сценарий:
#!/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()
Полное раскрытие: я поддерживаю явный модуль. Он предназначен для того, чтобы упростить использование явных ожиданий для таких ситуаций, когда сайты медленно загружаются в динамический контент на основе пользовательских взаимодействий. Вы могли бы заменить все вызовы waiter.XXX
выше с прямыми явными ожиданиями.
Я не вижу существенного недостатка в вашем блоке кода как такового. Но вот несколько рекомендаций через это решение & amp; выполнение этого автоматизированного тестового сценария:
JavaScript
& amp; Ajax Calls
находятся в игре, и обработка которых выходит за рамки этого Вопроса. wait
для HTML DOM для правильной рендеринга. FirefoxProfile
, как указано в моем коде ниже. browser.maximize_window()
browser.quit()
в конце, вам не нужно использовать browser.close()
time.sleep()
на любой из ImplicitlyWait
или ExplicitWait
или FluentWait
. #!/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)
Дайте мне знать, если это ответит на ваш вопрос.
ImplicitlyWait
или ExplicitWait
или FluentWait.
? Удостоверьтесь, что он загружен, прежде чем procedured станет лучшей идеей.
– bkcollection
26 May 2017 в 08:27
ImplicitlyWait
один раз в начале вашего скрипта, так что Selenium будет ждать последовательно. Вы также можете использовать ExplicitWait
, чтобы определенные элементы были видимыми / кликабельными в HTML DOM. В качестве альтернативы вы можете использовать FluentWait
, чтобы ускорить выполнение, частым опросом, игнорируя Исключения. В Make sure it is downloaded before procedd
вы можете использовать urllib.request.urlretrieve
модуль, который будет блокироваться до завершения загрузки. благодаря
– DebanjanB
26 May 2017 в 11:45
time.sleep
- плохая идея. благодаря
– bkcollection
26 May 2017 в 12:04
Я не пробовал на упомянутом вами сайте, однако следующий код работает отлично и загружает ZIP. если вы не можете загрузить zip, тип Mime может быть другим. вы можете использовать браузер Chrome и сетевой контроль, чтобы проверить тип mime файла, который вы пытаетесь загрузить.
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/")
profile.set_preference('browser.helperApps.neverAsk.saveToDisk', 'application/zip')
browser = webdriver.Firefox(profile)
browser.get("http://www.colorado.edu/conflict/peace/download/peace.zip")
Возьмите его за рамки селена. Измените настройки предпочтений так, чтобы при щелчке ссылки (сначала проверьте, действительно ли ссылка), она дает вам всплывающее окно с просьбой сохранить, теперь используйте sikuli http://www.sikuli.org/ для нажмите на всплывающее окно. Мимические типы не всегда работают, и нет черного и белого ответа, почему он не работает.
Причина в том, что веб-страница медленно загружается. Я добавил ожидание через 20 секунд после открытия ссылки на веб-страницу
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()
Не возвращается ошибка.
Дополнительно, /zip
неверен тип MIME. Изменить на profile.set_preference('browser.helperApps.neverAsk.saveToDisk', 'application/zip')
Окончательная коррекция:
#!/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')
@retry(Exception, tries=5, delay=3)
и@contextmanager
? Есть ли другой общий модуль, который может использоваться для заменыretry
иexplicit
? Pythonanywhere не имеет этих двух модулей. – bkcollection 26 May 2017 в 02:22retry
иexplicit
?https://help.pythonanywhere.com/pages/InstallingNewModules/
– Levi Noecker 26 May 2017 в 02:37print "firefox"
и снова должен повториться. Это происходит как 2 раза из трех – bkcollection 26 May 2017 в 08:28