BitMEXからCSVのリストを抽出しようとしています。ページは、ディレクトリの実際のインデックスをレンダリングするために、いくつかの(ロードがかなり遅い)Javascriptを実行します(なぜこれを選択したのか、私を超えています-おそらく難読化されていますか?)。
SeleniumのPython言語バインディングを使用する次のPython3.xコードがあります。
#!/bin/python3
import datetime
from urllib import request
import sys
from sys import argv
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from time import sleep
from bs4 import BeautifulSoup
from selenium.webdriver.chrome.options import Options
DOM_LOAD_WAIT = 60
COMMENT_CHAR = '#'
def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
def get_html(url):
# configure headlessness for the webdriver
options = Options()
options.headless = True
driver = webdriver.Chrome(options=options)
driver.implicitly_wait(DOM_LOAD_WAIT)
# constantly retry until success
while True:
try:
driver.get(url)
break
except KeyboardInterrupt:
exit(1)
except:
eprint("Retrying \"{}\"...".format(url))
continue
return driver
def get_results(url):
driver = None
try:
driver = get_html(url)
element = WebDriverWait(driver, DOM_LOAD_WAIT).until(
EC.presence_of_element_located((By.TAG_NAME, "pre"))
)
finally:
driver.quit()
print(driver.find_elements_by_tag_name("a"))
if __name__ == "__main__":
url = "https://public.bitmex.com/?prefix=data/quote/"
get_results(url.strip())
print("", end=None, flush=True) # flush stdout!
問題は、スクリプトが、私が求めている最終的なページソースではなく、最初のページソースを取得することです(つまり、Javascriptが完全に実行された後、時間がかかる場合があります)。
$ ./script.py
<html><head>
<title>public.bitmex.com</title>
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self'; connect-src https://s3-eu-west-1.amazonaws.com; script-src 'sha384-3ceskX3iaEnIogmQchP8opvBy3Mi7Ce34nWjpBIwVTHfGYWQS9jwHDVRnpKKHJg7' 'sha384-n0cKBy1+1+ACIC9J2XunFZItQjpIi1bilP1FCayDxybB40OcUY1ipK4Qjr856KWI' 'sha384-Rncjr7coAsbMCINMdkum6h64TPVhqlDpqulDQB/a68yABAgOU21duBLDdlm86oKP'; child-src 'none'; object-src 'none'; require-sri-for script style; block-all-mixed-content;">
</head>
<body>
<div id="navigation"></div>
<div id="listing"><img src="//public.bitmex.com/ajaxload-circle.gif"></div>
<script type="text/javascript" src="https://public.bitmex.com/jquery.min.js" integrity="sha384-3ceskX3iaEnIogmQchP8opvBy3Mi7Ce34nWjpBIwVTHfGYWQS9jwHDVRnpKKHJg7" crossorigin="anonymous"></script>
<script type="text/javascript" src="https://public.bitmex.com/init.js" integrity="sha384-n0cKBy1+1+ACIC9J2XunFZItQjpIi1bilP1FCayDxybB40OcUY1ipK4Qjr856KWI" crossorigin="anonymous"></script>
<script type="text/javascript" src="https://public.bitmex.com/list.js" integrity="sha384-Rncjr7coAsbMCINMdkum6h64TPVhqlDpqulDQB/a68yABAgOU21duBLDdlm86oKP" crossorigin="anonymous"></script>
</body></html>
具体的には、回転するローディングホイールのGIFのみを取得しますが、これは(言うまでもなく)非常に苛立たしいことです。
Javascriptが完全に実行された後にのみWebドライバーが制御を返すようにするにはどうすればよいですか?
コンテンツセキュリティポリシーの実装に一貫性がないため、ChromiumベースのWebドライバーを使用する必要があることに注意してください。
「最終変更日」というテキストが見つかるまで、ドライバードライバーを待機させることができます。
def get_results(url):
driver = None
try:
driver = get_html(url)
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//*[contains(text(), 'Last Modified')]")))
finally:
driver.quit()
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加