【问题标题】:Python Web Scraping - How to scrape this type of site?Python Web Scraping - 如何抓取此类网站?
【发布时间】:2019-11-21 00:21:06
【问题描述】:

好的,所以我需要抓取以下网页:https://www.programmableweb.com/category/all/apis?deadpool=1

这是一个 API 列表。大约有 22,000 个 API 可供抓取。


我需要:

1) 获取表中每个 API 的 URL(第 1-889 页),并抓取以下信息:

  • API 名称
  • 说明
  • 类别
  • 已提交

2) 然后我需要从每个 URL 中抓取大量信息。

3) 将数据导出为 CSV


问题是,我对如何思考这个项目有点迷茫。据我所知,没有进行 AJAX 调用来填充表格,这意味着我将不得不直接解析 HTML(对吗?)


在我的脑海里,逻辑应该是这样的:

  1. 使用 requests 和 BS4 库来刮表

  2. 然后,以某种方式从每一行中获取 HREF

  3. 访问该 HREF,抓取数据,移动到下一个

  4. 冲洗并重复所有表格行。


我是否走在正确的轨道上,这对于 requests 和 BS4 是否可行?

这是我一直试图解释的一些screenshots

非常感谢您提供的任何帮助。这让我头疼哈哈

【问题讨论】:

  • 到目前为止你有什么尝试!
  • 你问的问题是什么?如果您只是询问 BS4 和 Requests 是否可以做到这一点,答案是(很可能)是的。

标签: python web-scraping beautifulsoup python-requests


【解决方案1】:

这里我们使用requestsBeautifulSouppandas

import requests
from bs4 import BeautifulSoup
import pandas as pd

url = 'https://www.programmableweb.com/category/all/apis?deadpool=1&page='

num = int(input('How Many Page to Parse?> '))
print('please wait....')
name = []
desc = []
cat = []
sub = []
for i in range(0, num):
    r = requests.get(f"{url}{i}")
    soup = BeautifulSoup(r.text, 'html.parser')
    for item1 in soup.findAll('td', attrs={'class': 'views-field views-field-title col-md-3'}):
        name.append(item1.text)
    for item2 in soup.findAll('td', attrs={'class': 'views-field views-field-search-api-excerpt views-field-field-api-description hidden-xs visible-md visible-sm col-md-8'}):
        desc.append(item2.text)
    for item3 in soup.findAll('td', attrs={'class': 'views-field views-field-field-article-primary-category'}):
        cat.append(item3.text)
    for item4 in soup.findAll('td', attrs={'class': 'views-field views-field-created'}):
        sub.append(item4.text)

result = []
for item in zip(name, desc, cat, sub):
    result.append(item)

df = pd.DataFrame(
    result, columns=['API Name', 'Description', 'Category', 'Submitted'])
df.to_csv('output.csv')

print('Task Completed, Result saved to output.csv file.')

结果可在线查看:Check Here

输出简单:

现在为href解析:

import requests
from bs4 import BeautifulSoup
import pandas as pd

url = 'https://www.programmableweb.com/category/all/apis?deadpool=0&page='

num = int(input('How Many Page to Parse?> '))
print('please wait....')

links = []
for i in range(0, num):
    r = requests.get(f"{url}{i}")
    soup = BeautifulSoup(r.text, 'html.parser')
    for link in soup.findAll('td', attrs={'class': 'views-field views-field-title col-md-3'}):
        for href in link.findAll('a'):
            result = 'https://www.programmableweb.com'+href.get('href')
            links.append(result)

spans = []
for link in links:
    r = requests.get(link)
    soup = soup = BeautifulSoup(r.text, 'html.parser')
    span = [span.text for span in soup.select('div.field span')]
    spans.append(span)

data = []
for item in spans:
    data.append(item)

df = pd.DataFrame(data)
df.to_csv('data.csv')
print('Task Completed, Result saved to data.csv file.')

在线查询结果:Here

示例视图如下:

如果您希望将这两个 csv 文件放在一起,那么代码如下:

import pandas as pd

a = pd.read_csv("output.csv")
b = pd.read_csv("data.csv")
merged = a.merge(b)
merged.to_csv("final.csv", index=False)

在线结果:Here

【讨论】:

  • 哇!这是一个很大的帮助人,我已经研究了近一个小时的代码,从现在开始我将使用它作为参考。太感谢了!我有一个问题,使用 panda - 是否可以提取非表格元素。更具体地说,页面中显示“SDK”、“文章”、“如何”等数字的部分。它是一个
      与 class="nav nav-tabs menu hidden-xs listprofile-display-count-风格”。
  • @Luke 我在你的案子上花了几个小时:)。如果我满足您的目标,请接受我的回答。不客气,兄弟。
  • @Luke Aha 我有你的问题,例如https://www.programmableweb.com/api/google-maps 所以你想提取SDKS
  • @Luke 你确实可以通过beautifulsoup 做到这一点。 pandas 是 Python 编程语言的易于使用的数据结构和数据分析工具。阅读它pandas.pydata.org
  • 绝对!你帮了我很多!是的,SDK 以及该部分中的其他信息。是否可以将上述所有数据写入同一个 CSV 文件?
【解决方案2】:

如果你打算继续研究,你应该阅读更多关于 scraping 的内容。

from bs4 import BeautifulSoup
import csv , os , requests
from urllib import parse


def SaveAsCsv(list_of_rows):
    try:
        with open('data.csv', mode='a',  newline='', encoding='utf-8') as outfile:
            csv.writer(outfile).writerow(list_of_rows)
    except PermissionError:
        print("Please make sure data.csv is closed\n")

if os.path.isfile('data.csv') and os.access('data.csv', os.R_OK):
    print("File data.csv Already exists \n")
else:
    SaveAsCsv([ 'api_name','api_link','api_desc','api_cat'])
BaseUrl = 'https://www.programmableweb.com/category/all/apis?deadpool=1&page={}'
for i in range(1, 890):
    print('## Getting Page {} out of 889'.format(i))    
    url = BaseUrl.format(i)
    res = requests.get(url)
    soup = BeautifulSoup(res.text,'html.parser')
    table_rows = soup.select('div.view-content > table[class="views-table cols-4 table"] > tbody tr')
    for row in table_rows:
        tds = row.select('td')
        api_name = tds[0].text.strip()
        api_link = parse.urljoin(url, tds[0].find('a').get('href'))
        api_desc = tds[1].text.strip()
        api_cat  = tds[2].text.strip()  if len(tds) >= 3 else ''
        SaveAsCsv([api_name,api_link,api_desc,api_cat])

【讨论】:

  • @αԋɱҽԃαмєяιcαη 我每天都在刮,所以稍微调整一下。投票给它是幸运的。
猜你喜欢
  • 1970-01-01
  • 2019-06-08
  • 2021-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多