簡體   English   中英

python web 在同一 class 中爬行

[英]python web crawling in same class

我是 python 和網絡爬蟲的初學者。

考慮這個 web 站點: https://finance.yahoo.com/quote/AWR?p=AWR

我想爬行遠期股息和收益率,但它的工作原理很奇怪:它打印“除息日期”

這是我的代碼

import pandas as pd
import datetime
import requests
import yfinance as yf
import time
from requests.exceptions import ConnectionError
from bs4 import BeautifulSoup



def web_content_div(web_content,class_path):
    web_content_div = web_content.find_all('div',{'class': class_path})
    try:
        spans = web_content_div[0].find_all('span')
        texts = [span.get_text() for span in spans]
    except IndexError:
        texts = []
    
    return texts

def real_time_price(stock_code):
    
    url = 'https://finance.yahoo.com/quote/' + stock_code + '?p=' + stock_code 
   
    try :
        r = requests.get(url)
        web_content = BeautifulSoup(r.text,'lxml')
        texts = web_content_div(web_content, 'My(6px) Pos(r) smartphone_Mt(6px)')
        if texts != []:
            price, change = texts[0],texts[1]
        else:
            price , change = [] , []
    
    #############################################################it doesn't works#####################################################
        texts = web_content_div(web_content,'D(ib) W(1/2) Bxz(bb) Pstart(12px) Va(t) ie-7_D(i) ie-7_Pos(a) smartphone_D(b) smartphone_W(100%) smartphone_Pstart(0px) smartphone_BdB smartphone_Bdc($seperatorColor)')
        if texts != []:
            for count, div in enumerate(texts):
                if div == 'Forward Dividend & Yield':
                   dividend = texts[count + 1]
        else:
            dividend = []
    #############################################################it doesn't works#####################################################
        
        texts = web_content_div(web_content,'D(ib) W(1/2) Bxz(bb) Pstart(12px) Va(t) ie-7_D(i) ie-7_Pos(a) smartphone_D(b) smartphone_W(100%) smartphone_Pstart(0px) smartphone_BdB smartphone_Bdc($seperatorColor)')
        if texts != []:
            for count, EX in enumerate(texts):
                if EX == 'Ex-Dividend Date':
                    EXdate = texts[count + 1]
        else:
            EXdate = []


    
        texts = web_content_div(web_content,'D(ib) W(1/2) Bxz(bb) Pend(12px) Va(t) ie-7_D(i) smartphone_D(b) smartphone_W(100%) smartphone_Pend(0px) smartphone_BdY smartphone_Bdc($seperatorColor)')
        if texts != []:
            for count, vol in enumerate(texts):
                if vol == 'Volume':
                    volume = texts[count + 1]
        else:
            volume = []

   
        texts = web_content_div(web_content, 'D(ib) W(1/2) Bxz(bb) Pstart(12px) Va(t) ie-7_D(i) ie-7_Pos(a) smartphone_D(b) smartphone_W(100%) smartphone_Pstart(0px) smartphone_BdB smartphone_Bdc($seperatorColor)')
        if texts != []:
            for count, target in enumerate(texts):
                if target == '1y Target Est':
                    one_year_target = texts[count +1]

        else:
            one_year_target = []


    except ConnectionError:
        price, change,dividend, EXdate,volume,one_year_target = [],[],[],[],[],[]

    return price, change,dividend, EXdate,volume,one_year_target


stock=['awr','aapl']


while(True):
    info = []
    col = []
    time_stamp = datetime.datetime.now() - datetime.timedelta(hours=13)
    time_stamp = time_stamp.strftime('%Y-%M-%D %H:%M:%S')
    for stock_code in stock:
        price, change,dividend, EXdate,volume,one_year_target = real_time_price(stock_code)
        info.append(price)
        info.extend([change])
        info.extend([dividend])
        info.extend([EXdate])
        info.extend([volume])
        info.extend([one_year_target])
        time.sleep(5)

    col = [time_stamp]
    col.extend(info)
    print(col)

它打印

'2021-41-03/14/21 19:41:16', '72.16', '+0.38 (+0.53%)', 'Ex-Dividend Date', 'Feb 12, 2021', '288,352', '77.00',

出現此問題的原因是,由於某種原因,Yahoo 頁面沒有圍繞您要閱讀的值設置span

例如,這就是我看到的您鏈接的結果:

<tr class="Bxz(bb) Bdbw(1px) Bdbs(s) Bdc($seperatorColor) H(36px) " data-reactid="108">
  <td class="C($primaryColor) W(51%)" data-reactid="109">
    <span data-reactid="110">Forward Dividend &amp; Yield</span>
  </td>
  <td class="Ta(end) Fw(600) Lh(14px)" data-test="DIVIDEND_AND_YIELD-value" data-reactid="111">1.34 (1.86%)</td>
</tr>

因此,您需要自己匹配適當的td並獲取其文本而不是span ,而不是spans = web_content_div[0].find_all('span')

一個快速測試表明,僅使用它適用於該領域,但會破壞其他一些領域:

spans = web_content_div[0].find_all('td')

因此,這顯然不是完整的解決方案,但表明這確實是問題所在。 您需要提出一個與您感興趣的所有值相匹配的選擇標准。

另請注意,您反復調用web_content_div ,您也可以在其中檢索一次並重用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM