如何抓取网页数据(如何用一些有用的数据抓取一个网页数据(图))
优采云 发布时间: 2021-11-17 02:13如何抓取网页数据(如何用一些有用的数据抓取一个网页数据(图))
前不久在LearnML分论坛看到一个帖子。主机在这篇文章中提到他需要为他的机器学习项目抓取网络数据。很多人在回复中给出了自己的方法,主要是学习如何使用BeautifulSoup和Selenium。
我在一些数据科学项目中使用过 BeautifulSoup 和 Selenium。在本文中,我将向您展示如何抓取收录一些有用数据的网页并将其转换为 Pandas 数据结构(DataFrame)。
为什么要转换成数据结构?这是因为大多数机器学习库都可以处理 Pandas 数据结构,并且您只需稍作修改即可编辑您的模型。
首先,我们需要在维基百科上找一张表,转换成数据结构。我抓到的表格显示了维基百科上观看次数最多的运动员数据。
许多任务之一是浏览 HTML 树以获取我们需要的表格。
通过请求和正则表达式库,我们开始使用 BeautifulSoup。
from bs4 import BeautifulSoup
import requests
import re
import pandas as pd
复制代码
接下来,我们将从网页中提取 HTML 代码:
website_url = requests.get('https://en.wikipedia.org/wiki/Wikipedia:Multiyear_ranking_of_most_viewed_pages').text
soup = BeautifulSoup(website_url, 'lxml')
print(soup.prettify())
</a>
Disclaimers
Contact Wikipedia
<a>
复制代码
从语料库中采集所有表格,我们有一个很小的表面积可供搜索。
wiki_tables = soup.find_all('table', class_='wikitable')
wiki_tables
复制代码
因为有很多表,所以需要一种过滤它们的方法。
据我们所知,克里斯蒂亚诺·罗纳尔多(Cristiano Ronaldo)(也被称为葡萄牙足球运动员罗纳尔多)有一个锚标记,这在几张表中可能是独一无二的。
使用 Cristiano Ronaldo 文本,我们可以过滤那些由锚点标记的表格。此外,我们还发现了一些收录此锚标记的父元素。
links = []
for table in wiki_tables:
_table = table.find('a', string=re.compile('Cristiano Ronaldo'))
if not _table:
continue
print(_table)
_parent = _table.parent
print(_parent)
links.append(_parent)
Cristiano Ronaldo
Cristiano Ronaldo
Cristiano Ronaldo
Cristiano Ronaldo
Cristiano Ronaldo
Cristiano Ronaldo
复制代码
父元素只显示单元格。
这是一个带有浏览器 Web 开发工具的单元格。
parent_lst = []
for anchor in links:
_ = anchor.find_parents('tbody')
print(_)
parent_lst.append(_)
复制代码
使用 tbody,我们可以返回收录先前锚标记的其他表。
为了进一步过滤,我们可以在下表中搜索不同的标题:
for i in parent_lst:
print(i[0].find('tr'))
tr>
Rank*
Page
Views in millions
Rank
Page
Views in millions
Rank
Page
Sport
Views in millions
复制代码
第三个看起来很像我们需要的表。
接下来,我们开始创建必要的逻辑来提取和清理我们需要的细节。
sports_table = parent_lst[2]
complete_row = []
for i in sports_table:
rows = i.find_all('tr')
print('n--------row--------n')
print(rows)
for row in rows:
cells = row.find_all('td')
print('n-------cells--------n')
print(cells)
if not cells:
continue
rank = cells[0].text.strip('n')
page_name = cells[1].find('a').text
sport = cells[2].find('a').text
views = cells[3].text.strip('n')
print('n-------CLEAN--------n')
print(rank)
print(page_name)
print(sport)
print(views)
complete_row.append([rank, page_name, sport, views])
for i in complete_row:
print(i)
复制代码
分解一下:
sports_table = parent_lst[2]
complete_row = []
复制代码
下面我们从上面的列表中选择第三个元素。这是我们需要的表。
接下来,创建一个空列表来存储每一行的详细信息。遍历这个表时,创建一个循环来遍历表中的每一行,并将其保存到rows变量中。
for i in sports_table:
rows = i.find_all('tr')
print('n--------row--------n')
print(rows)
复制代码
for row in rows:
cells = row.find_all('td')
print('n-------cells--------n')
print(cells)
复制代码
建立一个嵌套循环。遍历上一个循环中保存的每一行。在遍历这些单元格时,我们将每个单元格保存在一个新变量中。
if not cells:
continue
复制代码
这段简短的代码使我们能够在从单元格中提取文本时避免出现空单元格并防止出现错误。
rank = cells[0].text.strip('n')
page_name = cells[1].find('a').text
sport = cells[2].find('a').text
views = cells[3].text.strip('n')
复制代码
在这里,我们将各种单元格清理成纯文本格式。清除的值存储在其列名下的变量中。
print('n-------CLEAN--------n')
print(rank)
print(page_name)
print(sport)
print(views)
complete_row.append([rank, page_name, sport, views])
复制代码
在这里,我们将这些值添加到行列表中。然后输出清洗后的值。
-------cells--------
[13
, Conor McGregor
, Mixed martial arts
, 43
]
-------CLEAN--------
13
Conor McGregor
Mixed martial arts
43
复制代码
将其转换为如下数据结构:
headers = ['Rank', 'Name', 'Sport', 'Views Mil']
df = pd.DataFrame(complete_row, columns=headers)
df
复制代码
现在您可以在机器学习项目中使用 pandas 数据结构。您可以使用您喜欢的库来拟合模型数据。