【问题标题】:How to webscrape a table with image and export to an Excel in Python?如何在 Python 中使用图像抓取表格并导出到 Excel?
【发布时间】:2020-12-23 10:25:01
【问题描述】:

我正在尝试从URL 中抓取一张表格

我可以使用 Scrapestorm 工具抓取表格数据。我是 python 新手,无法从 URL 获取数据。

from bs4 import BeautifulSoup

page = requests.get('https://pantheon.world/explore/rankings?show=people&years=-3501,2020')
soup = BeautifulSoup(page.text)

Excel 中所需的输出:

是否可以从网页中抓取表格数据以及图片?

【问题讨论】:

  • 如果它的动态内容是由javascript创建的,那么漂亮的汤不会有任何好处。
  • 在这种情况下哪一个会更好?有没有可以使用的包?
  • 你可以试试 selenium。

标签: python web-scraping beautifulsoup


【解决方案1】:

当然,这是可能的。然而,看到这个特定页面的 DOM 是如何使用 JavaScript 异步填充的,BeautifulSoup 将无法看到您尝试抓取的数据。通常,这是大多数人建议您使用 Selenium 或 PlayWright 等无头浏览器/网络驱动程序来模拟浏览会话的地方 - 但您很幸运。对于这个特定页面,您不需要无头浏览器或 Scrapestorm 或 BeautifulSoup - 您只需要第三方 requests 模块。当您访问此页面时,它恰好向提供 JSON 的 REST API 发出 HTTP GET 请求。 JSON 响应包含表中的所有信息。如果您记录浏览器的网络流量,您可以看到对 API 的请求:

这是响应 JSON 的样子 - 字典列表:

从中,您可以复制 API URL 和相关的查询字符串参数来制定您自己对该 API 的请求:

def main():

    import requests

    url = "https://api.pantheon.world/person_ranks"

    params = {
        "select": "name,l,l_,age,non_en_page_views,coefficient_of_variation,hpi,hpi_prev,id,slug,gender,birthyear,deathyear,bplace_country(id,country,continent,slug),bplace_geonameid(id,place,country,slug,lat,lon),dplace_country(id,country,slug),dplace_geonameid(id,place,country,slug),occupation_id:occupation,occupation(id,occupation,occupation_slug,industry,domain),rank,rank_prev,rank_delta",
        "birthyear": "gte.-3501",
        "birthyear": "lte.2020",
        "hpi": "gte.0",
        "order": "hpi.desc.nullslast",
        "limit": "50",
        "offset": "0"
    }

    response = requests.get(url, params=params)
    response.raise_for_status()

    for person in response.json():
        print(f"{person['name']} was a {person['occupation']['occupation']}")
    
    return 0


if __name__ == "__main__":
    import sys
    sys.exit(main())

输出:

Muhammad was a RELIGIOUS FIGURE
Genghis Khan was a MILITARY PERSONNEL
Leonardo da Vinci was a INVENTOR
Isaac Newton was a PHYSICIST
Ludwig van Beethoven was a COMPOSER
Alexander the Great was a MILITARY PERSONNEL
Aristotle was a PHILOSOPHER
...

从这里将这些信息写入 CSV 或 excel 文件很简单。您可以使用params 查询字符串参数字典中的"limit": "50""offset": "0" 键值对来检索不同人的信息。

编辑 - 要获取每个人的缩略图,您需要构建以下形式的 URL:

https://pantheon.world/images/profile/people/{PERSON_ID}.jpg

其中{PERSON_ID} 是与给定人员的id 键关联的值:

...

for person in response.json():
    image_url = f"https://pantheon.world/images/profile/people/{person['id']}.jpg"
    print(f"{person['name']}'s image URL: {image_url}")

如果您将 openpyxl 用于您的 excel 文件,这里有一个 useful answer,它向您展示了如何在给定图像 URL 的单元格中插入图像。但是,我建议您使用 requests 而不是 urllib3 来向图像发出请求。

【讨论】:

  • 非常感谢您的回答。是否可以刮取每一行的图像??
  • @User789 是的,每个人的图像的 URL 看起来都遵循以下模式:https://pantheon.world/images/profile/people/{PERSON_ID}.jpg,其中{PERSON_ID} 将是给定人员的 id 键值对的值在 JSON 响应中。例如,成吉思汗的 ID 为 17414699,因此 URL 为 https://pantheon.world/images/profile/people/17414699.jpg
  • 请不要介意,您也可以将其添加到答案中
  • @User789 当然,我已经在最底部编辑了我的答案。看看吧。
猜你喜欢
  • 1970-01-01
  • 2021-11-27
  • 1970-01-01
  • 2020-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-08
相关资源
最近更新 更多