2017-06-16 15 views
-1

我試圖從網上以編程方式收集6000股票的數據,我使用Python 3.6硒webdriver Firefox。 [我打算使用BeautifulSoup來解析HTML,但它似乎每當我更新網頁,鏈接不會改變,湯沒有處理Javascript]python webscraping在循環中失敗,但工程時,我手動執行

無論如何,當我創建一個for循環做到這一點,我的代碼中的特定行share_price = driver.find_element_by_css_selector(".highcharts-root > g:nth-child(25) > text:nth-child(2)")大部分時間都出錯了(雖然它工作了幾次,所以我相信我的代碼很好)。但是,如果我手動執行它(它可以複製並粘貼到Python IDLE並運行它),它就可以正常工作。我試圖使用time.sleep(4)來允許在我從後臺打撈任何東西之前加載網頁,但似乎這不是解決方案。現在我已經沒有任何提示。任何人都可以幫我解開這個問題嗎?

下面是我的代碼:

from selenium import webdriver 
import time 
import pyautogui 
filename = "historical_price_marketcap.csv" 
f = open(filename,"w") 
headers = "stock_ticker, share_price, market_cap\n" 
f.write(headers) 
driver = webdriver.Firefox() 
def get_web(): 
    driver.get("https://stockrow.com") 
import csv 
with open("TICKER.csv") as file: 
     read = csv.reader(file) 
     TICKER=[] 
     for row in read: 
       ticker = row[0][1:-1] 
       TICKER.append(ticker) 
for Ticker in range(len(TICKER)): 
    get_web() 
    time.sleep(3) 
    pyautogui.click(425, 337) 
    pyautogui.typewrite(TICKER[Ticker],0.25) 
    time.sleep(2) 
    pyautogui.press("enter") 
    time.sleep(2) 
    pyautogui.click(268, 337) 
    pyautogui.press("backspace") 
    time.sleep(2) 
    pyautogui.typewrite('Stock Price',0.25) 
    time.sleep(2) 
    pyautogui.press("enter") 
    time.sleep(2) 

    pyautogui.click(702, 427) 
    for i in range(int(10)): 
      pyautogui.press("backspace") 
    time.sleep(2) 
    pyautogui.typewrite("2013-12-01",0.25) 
    pyautogui.press("enter") 
    time.sleep(2) 

    pyautogui.click(882, 425) 
    for k in range(10): 
      pyautogui.press("backspace") 
    time.sleep(2) 
    pyautogui.typewrite("2013-12-31",0.25) 
    pyautogui.press("enter") 
    time.sleep(2) 

    pyautogui.click(1317, 318) 
    for j in range(3): 
      pyautogui.press("down") 

    time.sleep(10) 
    share_price = driver.find_element_by_css_selector(".highcharts-root > g:nth-child(25) > text:nth-child(2)") 
    get_web() 
    time.sleep(3) 
    pyautogui.click(425, 337) 
    pyautogui.typewrite(TICKER[Ticker],0.25) 
    time.sleep(2) 
    pyautogui.press("enter") 
    time.sleep(2) 
    pyautogui.click(268, 337) 
    pyautogui.press("backspace") 
    time.sleep(2) 
    pyautogui.typewrite('Market Cap',0.25) 
    time.sleep(2) 
    pyautogui.press("enter") 
    time.sleep(2) 

    pyautogui.click(702, 427) 
    for i in range(int(10)): 
      pyautogui.press("backspace") 
    time.sleep(2) 
    pyautogui.typewrite("2013-12-01",0.25) 
    pyautogui.press("enter") 
    time.sleep(2) 

    pyautogui.click(882, 425) 
    for k in range(10): 
      pyautogui.press("backspace") 
    time.sleep(2) 
    pyautogui.typewrite("2013-12-31",0.25) 
    pyautogui.press("enter") 
    time.sleep(2) 

    pyautogui.click(1317, 318) 
    for j in range(3): 
      pyautogui.press("down") 

    time.sleep(10) 
    market_cap = driver.find_element_by_css_selector(".highcharts-root > g:nth-child(28) > text:nth-child(2)") 
f.close() 

似乎兩行是竊聽我是share_price = driver.find_element_by_css_selector(".highcharts-root > g:nth-child(25) > text:nth-child(2)")這裏是Python的錯誤消息:

Traceback (most recent call last): 
    File "C:\Users\HENGBIN\Desktop\get_historical_data.py", line 65, in <module> 
    share_price = driver.find_element_by_css_selector(".highcharts-root > g:nth-child(25) > text:nth-child(2)") 
    File "E:\Program Files\python3.6.1\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 457, in find_element_by_css_selector 
    return self.find_element(by=By.CSS_SELECTOR, value=css_selector) 
    File "E:\Program Files\python3.6.1\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 791, in find_element 
    'value': value})['value'] 
    File "E:\Program Files\python3.6.1\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 256, in execute 
    self.error_handler.check_response(response) 
    File "E:\Program Files\python3.6.1\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 194, in check_response 
    raise exception_class(message, screen, stacktrace) 
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: .highcharts-root > g:nth-child(25) > text:nth-child(2) 

它不工作的大部分在循環中的時間,但工作正常,如果我在Python IDLE中手動運行它。我不知道發生了什麼.........

回答

0

腳本中有幾件事情,我會做不同的事情。 首先 - 嘗試擺脫pyautogui。硒具有點擊功能(檢出this SO-question)和發送各種密鑰(檢出this SO-question)。另外,當您更改瀏覽器中的內容(使用pyautogui)時,我的經驗是硒並不總是意識到這些變化。這可以解釋你在尋找硒時尋找元素pyautogui時遇到的問題。其次:你的get_web()函數可能會導致問題。一般而言,函數內部的內容必須返回 - 或聲明爲全局 - 才能在函數外部訪問。驅動程序打開你的網頁是全局的(你可以在函數之外實例化它),但是函數內的url是局部的,這意味着訪問函數之外的內容可能會遇到問題。我建議你擺脫功能的(因爲它確實沒有做任何事情,除了打開URL),並簡單地只需更換函數調用的代碼如下所示:

for Ticker in range(len(TICKER)): 
    driver.get("https://stockrow.com") 
    time.sleep(3) 
    # insert keys, click and so on... 

這應該有可能爲你使用seleniums driver.find_elements ...-方法。

第三:我假設你想從網站中提取一些數據。如果是這樣,請用除硒之外的東西進行解析。硒是一個緩慢的解析器。您可以嘗試使用BeautifulSoup。

一旦網站被加載加載任何你想在BeautifulSoup HTML和提取物(有一個SO-question here,那將告訴你如何去有關)

from bs4 import BeautifulSoup 
..... 
html = driver.page_source 
soup = BeautifulSoup(html, "html.parser") 
element_you_want_to_retrieve = soup.find('tag_name', attrs={'key': 'value'}) 
+0

beautifulsoup可能不是一個很好的選擇,因爲網絡正在使用JavaScript。 –

0

但這個網站是你真正應該做的就是點擊自己的網站製作的API調用。使用Chromes檢查器工具。你會發現它會查詢三個API,你可以直接調用並避免整個硒問題。

蘋果的URL看起來是這樣的:

url = 'https://stockrow.com/api/fundamentals.json?indicators[]=0&tickers[]=APPL' 

因此,與請求庫,你可以檢索內容爲JSON像這樣:

import requests 
from pprint import pprint 
url = 'https://stockrow.com/api/fundamentals.json?indicators[]=0&tickers[]=AAPL' 
response = requests.get(url).json() 
pprint(response) 
+0

謝謝,那好像不錯! –

+0

很酷。請將問題標記爲已回答,這樣其他人就不會浪費時間去解決問題 - 並且解決了問題的答案。 – jlaur

相關問題