iT邦幫忙

1

python抓網站資料的問題

  • 分享至 

  • xImage

用Python抓網站資料
如該網有2000筆資料 顯示100筆資料 剩下資料需按"加載更多"鈕
當已顯示全部資料時 還是只能抓前100筆資料 抓不到剩下資料
df = pd.read_html('https://tw.tradingview.com/markets/stocks-taiwan/market-movers-all-stocks/')

請問有何建議??

看更多先前的討論...收起先前的討論...
haward79 iT邦研究生 1 級 ‧ 2024-09-14 12:58:20 檢舉
按"加載更多"鈕應該是在網頁上按的吧?
python程式並不會因此受到影響
他在讀的時候還是只讀到前 100 筆
因為 pd 不會自動幫你按 "加載更多"

解決方法:
1. 找 API:看看網頁是否有提供 API 可以一口氣抓全部
2. 找可互動的 Python Library:例如 selenium,可以寫程式讓 selenium 按"加載更多"後再開始爬資料
Kevin_0 iT邦新手 5 級 ‧ 2024-09-16 09:42:35 檢舉
對! 我是先用 selenium 按"加載更多"後
再用pd.read_html()抓資料 但只讀到前 100 筆 無法抓"全部"資料
pd.read_html()不是抓網頁"全部"資料嗎?
haward79 iT邦研究生 1 級 ‧ 2024-09-16 10:07:15 檢舉
@Kevin_0
海綿大大的方法會比較直接,可以試試
或是把你的完整 code 丟上來方便大家幫你找問題
haward79 iT邦研究生 1 級 ‧ 2024-09-16 10:11:10 檢舉
@Kevin_0
理論上是用 selenium 按下按鈕後,再讀 selenium 那邊的網頁 source code。不過根據你的描述「df = pd.read_html('https://tw.tradingview.com/markets/stocks-taiwan/market-movers-all-stocks/')」,這邊似乎跟 selenium 無關,而是直接重新訪問網址抓資料。
froce iT邦大師 1 級 ‧ 2024-09-16 14:33:09 檢舉
pd.read_html只會得到第一次加載的html,後面的除非你先用selenium下載完,要不然讀不到。
這邊教你如何去得到動態產生的html code
https://www.repeato.app/how-to-get-the-html-source-of-a-webelement-in-selenium-webdriver-using-python/

這邊跟你說pd.read_html除了網址也能直接讀html碼。
https://pandas.pydata.org/docs/reference/api/pandas.read_html.html

但建議還是用下面海綿寶寶給的,從網頁api的觀點去取資料。
Kevin_0 iT邦新手 5 級 ‧ 2024-09-18 10:58:35 檢舉
是用 selenium 按下按鈕(Xpath)後,再讀22次(100筆x22次=2200筆) 網頁顯示全部資料。

# 加載更多
for i in range(22):
try: # 使用 try,測試內容是否正確
page=driver.find_element(By.XPATH,"/html/body/div[3]/div[4]/div/div[2]/div/div[4]/div[3]/button/span")
page.click()
time.sleep(12)
except: # 如果 try 的內容發生錯誤,就執行 except 裡的內容
pass

用「df = pd.read_html('https://tw.tradingview.com/markets/stocks-taiwan/market-movers-all-stocks/')」,直接抓資料。 是有抓到資料 但只有100筆
所以想知道如何抓全部

非相關科系的我 "海綿寶寶給的,從網頁api的觀點去取資料"還研究看看
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

0
haward79
iT邦研究生 1 級 ‧ 2024-09-18 15:08:48
最佳解答

僅供參考


from time import sleep
import pandas as pd
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException


driver = webdriver.Firefox()
driver.get('https://tw.tradingview.com/markets/stocks-taiwan/market-movers-all-stocks/')

# 只要「載入更多」的按鈕還在,就一直按按鈕
while True:
    sleep(3)

    try:
        # 尋找「載入更多」按鈕
        load_button = driver.find_element(By.CSS_SELECTOR, '.button-SFwfC2e0')

        # 按下「載入更多」按鈕
        load_button.click()
    
    # 「載入更多」按鈕不見時會跑進這
    except NoSuchElementException:
        break

# 用 pandas 抓取網頁上的所有表格
tables = pd.read_html(driver.page_source)

# 將抓到的表格以 csv 格式存下來,可用 Excel 檢查結果
# 2.csv 應該就是你要的東西
for i, table in enumerate(tables):
    table.to_csv(f'{i+1}.csv', index=False)

driver.quit()

5
海綿寶寶
iT邦大神 1 級 ‧ 2024-09-14 14:21:52

參考看看

import requests
import pandas as pd

url = 'https://scanner.tradingview.com/taiwan/scan'

# 唯一要改的是 range 的 0,200, 看200要改成多少
payload = {'columns':['name','description','logoid','update_mode','type','typespecs','close','pricescale','minmov','fractional','minmove2','currency','change','volume','relative_volume_10d_calc','market_cap_basic','fundamental_currency_code','price_earnings_ttm','earnings_per_share_diluted_ttm','earnings_per_share_diluted_yoy_growth_ttm','dividends_yield_current','sector.tr','market','sector','recommendation_mark'],'ignore_unknown_fields':false,'options':{'lang':'zh_TW'},'range':[0,200],'sort':{'sortBy':'name','sortOrder':'asc','nullsFirst':false},'preset':'all_stocks'}

# Make the POST request
response = requests.post(url, json=payload)

# Check if the request was successful
if response.status_code == 200:
    # Get the JSON data from the response
    data = response.json()
    
    # Convert the JSON data to a pandas DataFrame
    df = pd.DataFrame(data)
    
    # Display the first few rows of the DataFrame
    print(df.head())
else:
    print(f"Request failed with status code: {response.status_code}")
Kevin_0 iT邦新手 5 級 ‧ 2024-09-16 09:44:57 檢舉

謝謝 我試試

我要發表回答

立即登入回答