【问题标题】:Getting 404 error for certain stocks and pages on yahoo finance python在 yahoo Finance python 上的某些股票和页面出现 404 错误
【发布时间】:2021-09-16 09:54:23
【问题描述】:

我正在尝试通过此 URL https://finance.yahoo.com/quote/AAPL/key-statistics?p=AAPL 从雅虎财经中抓取数据。运行下面的 python 代码后,我得到以下 HTML 响应

import numpy as np
import pandas as pd
from bs4 import BeautifulSoup
import requests, lxml
from lxml import html

stockStatDict = {}
stockSymbol = 'AAPL'
URL = 'https://finance.yahoo.com/quote/'+ stockSymbol + '/key-statistics?p=' + stockSymbol
page = requests.get(URL)
print(page.text)


<!DOCTYPE html>
  <html lang="en-us"><head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <meta charset="utf-8">
      <title>Yahoo</title>
      <meta name="viewport" content="width=device-width,initial-scale=1,minimal-ui">
      <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
      <style>
  html {
      height: 100%;
  }
  body {
      background: #fafafc url(https://s.yimg.com/nn/img/sad-panda-201402200631.png) 50% 50%;
      background-size: cover;
      height: 100%;
      text-align: center;
      font: 300 18px "helvetica neue", helvetica, verdana, tahoma, arial, sans-serif;
  }
  table {
      height: 100%;
      width: 100%;
      table-layout: fixed;
      border-collapse: collapse;
      border-spacing: 0;
      border: none;
  }
  h1 {
      font-size: 42px;
      font-weight: 400;
      color: #400090;
  }
  p {
      color: #1A1A1A;
  }
  #message-1 {
      font-weight: bold;
      margin: 0;
  }
  #message-2 {
      display: inline-block;
      *display: inline;
      zoom: 1;
      max-width: 17em;
      _width: 17em;
  }
      </style>
  <script>
    document.write('<img src="//geo.yahoo.com/b?s=1197757129&t='+new Date().getTime()+'&src=aws&err_url='+encodeURIComponent(document.URL)+'&err=%<pssc>&test='+encodeURIComponent('%<{Bucket}cqh[:200]>')+'" width="0px" height="0px"/>');var beacon = new Image();beacon.src="//bcn.fp.yahoo.com/p?s=1197757129&t="+new Date().getTime()+"&src=aws&err_url="+encodeURIComponent(document.URL)+"&err=%<pssc>&test="+encodeURIComponent('%<{Bucket}cqh[:200]>');
  </script>
  </head>
  <body>
  <!-- status code : 404 -->
  <!-- Not Found on Server -->
  <table>
  <tbody><tr>
      <td>
      <img src="https://s.yimg.com/rz/p/yahoo_frontpage_en-US_s_f_p_205x58_frontpage.png" alt="Yahoo Logo">
      <h1 style="margin-top:20px;">Will be right back...</h1>
      <p id="message-1">Thank you for your patience.</p>
      <p id="message-2">Our engineers are working quickly to resolve the issue.</p>
      </td>
  </tr>
  </tbody></table>
  </body></html>

我很困惑,因为我使用以下代码在此 URL https://finance.yahoo.com/quote/AAPL?p=AAPL 的摘要选项卡上抓取数据没有问题

import numpy as np
import pandas as pd
from bs4 import BeautifulSoup
import requests, lxml
from lxml import html
stockDict = {}

stockSymbol = 'AAPL'
URL = 'https://finance.yahoo.com/quote/'+ stockSymbol + '?p=' + stockSymbol
page = requests.get(URL)
print(page.text)

soup = BeautifulSoup(page.content, 'html.parser')


stock_data = soup.find_all('table')

stock_data
for table in stock_data:
    
    trs = table.find_all('tr')
    
    for tr in trs:
        
        
        tds = tr.find_all('td')
        
        if len(tds) > 0:
         
            stockDict[tds[0].get_text()] = [tds[1].get_text()]


stock_sum_df = pd.DataFrame(data=stockDict)
print(stock_sum_df.head())
print(stock_sum_df.info())

有人知道我做错了什么吗?如果这有什么不同的话,我也在使用免费版的 yahoo Finance。

【问题讨论】:

    标签: python web-scraping beautifulsoup http-status-code-404


    【解决方案1】:

    所以我发现了你的问题。

    User-Agent 请求标头包含一个特征字符串,允许网络协议对等方识别请求软件用户代理的应用程序类型、操作系统、软件供应商或软件版本。在服务器端验证 User-Agent 标头是一种常见操作,因此请务必使用有效浏览器的 User-Agent 字符串以避免被阻止。

    来源http://go-colly.org/articles/scraping_related_http_headers/)

    您唯一需要做的就是设置一个合法的用户代理。因此添加标题以模拟浏览器:

    # This is a standard user-agent of Chrome browser running on Windows 10 
    headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36' } 
    

    例子:

    import requests 
    headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'}
    stockSymbol = 'AAPL'
    url = 'https://finance.yahoo.com/quote/'+ stockSymbol + '/key-statistics?p=' + stockSymbol
    resp = requests.get(url, headers=headers, timeout=5).text 
    print(resp)
    

    此外,您可以添加另一组标头来伪装成合法浏览器。添加更多这样的标题:

    headers = { 
        'User-Agent'      : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36', 
        'Accept'          : 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 
        'Accept-Language' : 'en-US,en;q=0.5',
        'DNT'             : '1', # Do Not Track Request Header 
        'Connection'      : 'close'
    }
    

    这些事情通常有两个主要原因:

    1. 反自动化系统(检测机器人/爬虫的系统)
    2. 倾向于根据您访问的浏览器对内容进行审核的网站。

    因此,在设计自动化系统时,在标题中提供用户代理总是一个好主意。

    【讨论】:

      【解决方案2】:

      不太确定导致问题的原因以及您的项目的意图是什么。但是,如果您的意图是能够使用 yahoo 财务数据做某事 - 而不是学习如何抓取数据,那么以下模块可以帮助您 (https://pypi.org/project/yahoo-finance/)

      【讨论】:

        猜你喜欢
        • 2020-07-08
        • 2018-09-17
        • 2021-12-12
        • 2011-01-17
        • 1970-01-01
        • 1970-01-01
        • 2013-08-04
        • 1970-01-01
        相关资源
        最近更新 更多