【问题标题】:Not able to scrape table data using BeautifulSoup from a website无法使用来自网站的 BeautifulSoup 抓取表数据
【发布时间】:2019-09-03 10:08:15
【问题描述】:

我正在关注一个在线教程 (https://www.analyticsvidhya.com/blog/2015/10/beginner-guide-web-scraping-beautiful-soup-python/),用于网页抓取 html 表格。当我按照教程进行操作时,我能够抓取表格数据,但是当我尝试从这个 (https://www.masslottery.com/games/lottery/search/results-history.html?game_id=15&mode=2&selected_date=2019-03-04&x=12&y=11) 网站抓取数据时,我无法这样做。

我之前尝试过使用scrapy,但得到了相同的结果。

这是我使用的代码。

import urllib.request

wiki = "https://www.masslottery.com/games/lottery/search/results-history.html?game_id=15&mode=2&selected_date=2019-03-04&x=12&y=11"
page = urllib.request.urlopen(wiki)
from bs4 import BeautifulSoup
soup = BeautifulSoup(page, "lxml")


all_tables=soup.find_all('table')


right_table=soup.find('table', class_='zebra-body-only')
print(right_table)

这是我在终端上运行此代码时得到的结果

<table cellspacing="0" class="zebra-body-only">
<tbody id="target-area">
</tbody>
</table>

虽然当我使用谷歌浏览器检查大众彩票网站时,这就是我所看到的

<table cellspacing="0" class="zebra-body-only"                                  <tbody id="target-area">
<tr class="odd">
<th>Draw #</th>
<th>Draw Date</th>
<th>Winning Number</th>
<th>Bonus</th>
</tr>
<tr><td>2107238</td>
<td>03/04/2019</td>
<td>01-04-05-16-23-24-27-32-34-41-42-44-47-49-52-55-63-65-67-78</td><td>No Bonus</td>
</tr>
<tr class="odd">
<td>2107239</td>
<td>03/04/2019</td>
<td>04-05-11-15-19-20-23-24-25-28-41-45-52-63-64-68-71-72-73-76</td><td>4x</td>
</tr> 
....(And so on)

我希望能够从这个表中提取数据。

【问题讨论】:

    标签: python html web-scraping html-table beautifulsoup


    【解决方案1】:

    是的,我会将您获得的数据保存在一个文件中,以查看您要查找的内容是否真的存在。 使用 open('stuff.html','w') 作为 f: f.write(response.text)

    unicode,试试: 导入编解码器 codecs.open(fp,'w','utf-8') as f:

    如果你没有看到你在寻找什么,你将不得不找出正确的 url 来加载,检查 chrome 开发者选项 这通常很难

    简单的方法是使用硒 确保你等到你要找的东西出现在页面上 (这是动态的)

    【讨论】:

      【解决方案2】:

      页面是动态的,所以它是在您发出请求后呈现的。您可以 a) 使用 JC1 的解决方案并访问 json 响应。或者你可以使用 Seleneium 来模拟打开浏览器,渲染页面,然后抓取表格:

      from bs4 import BeautifulSoup
      from selenium import webdriver
      
      
      url = 'https://www.masslottery.com/games/lottery/search/results-history.html?game_id=15&mode=2&selected_date=2019-03-04&x=12&y=11'  
      
      driver = webdriver.Chrome()
      driver.get(url)
      page = driver.page_source
      
      soup = BeautifulSoup(page, "lxml")
      
      all_tables=soup.find_all('table')
      
      
      right_table=soup.find('table', class_='zebra-body-only')
      

      另外附注:通常如果我看到 &lt;table&gt; 标签,我会让 Pandas 为我完成工作(注意,我被阻止访问该网站,所以无法测试这些):

      import pandas as pd
      from selenium import webdriver
      
      
      url = 'https://www.masslottery.com/games/lottery/search/results-history.html?game_id=15&mode=2&selected_date=2019-03-04&x=12&y=11'  
      
      driver = webdriver.Chrome()
      driver.get(url)
      page = driver.page_source
      
      # will return a list of dataframes
      tables = pd.read_html(page)
      
      # chose the dataframe you want from the list by it's position
      df = tables[0]
      

      【讨论】:

        【解决方案3】:

        发生这种情况是因为网站再次调用以加载结果。初始链接仅加载页面而不加载结果。使用 chrome 开发工具检查请求,您将能够找出需要复制的请求以获得结果。

        这意味着要得到结果,你可以只调用上面提到的请求,而不用调用网页。

        幸运的是,您必须调用的端点已经采用了不错的 JSON 格式。

        GET https://www.masslottery.com/data/json/search/dailygames/history/15/201903.json?_=1555083561238

        我假设1555083561238 是时间戳。

        【讨论】:

        • 我怎么称呼那个端点?抱歉,我对此真的很陌生。
        • 因为它是一个 GET 请求,只需用这个 URL 替换你的“wiki”变量。您可能想查看 python requests 包,因为它更详细地用于使用不同方法(GET、PUT、POST 等)调用各种 URL
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-26
        • 1970-01-01
        • 1970-01-01
        • 2019-12-15
        • 2019-09-26
        相关资源
        最近更新 更多