Beautiful Soup 和 scraping 维基百科条目:
Beautiful Soup and scraping wikipedia entries:
初学者 BeautifulSoup,我正在尝试提取
来自此维基百科的公司名称、等级和收入 link。
https://en.m.wikipedia.org/wiki/List_of_largest_Internet_companies
到目前为止我使用的代码是:
from bs4 import BeautifulSoup
import requests
url = "https://en.wikiepdia.org"
req = requests.get(url)
bsObj = BeautifulSoup(req.text, "html.parser")
data = bsObj.find('table',{'class':'wikitable sortable mw-collapsible'})
revenue=data.findAll('data-sort-value')
我意识到甚至 'data' 也不能正常工作,因为当我将它传递到 flask 网站时它没有任何值。
有人可以建议修复和实现上述目标的最优雅的方法,以及一些关于我们在抓取(和格式)时在 HTML 中寻找的最佳方法的建议.
关于这个 link, https://en.m.wikipedia.org/wiki/List_of_largest_Internet_companies 我不确定我要用来提取什么 - table class, div class 或正文 class。此外,如何进一步提取 link 和树下的收入。
我也试过:
data = bsObj.find_all('table', class_='wikitable sortable mw-collapsible')
它运行服务器没有错误。但是,在网页“[]”
上只显示一个空列表
基于以下一个答案:我将代码更新为以下内容:
url = "https://en.wikiepdia.org"
req = requests.get(url)
bsObj = BeautifulSoup(req.text, "html.parser")
mydata=bsObj.find('table',{'class':'wikitable sortable mw-collapsible'})
table_data=[]
rows = mydata.findAll(name=None, attrs={}, recursive=True, text=None, limit=None, kwargs='')('tr')
for row in rows:
cols=row.findAll('td')
row_data=[ele.text.strip() for ele in cols]
table_data.append(row_data)
data=table_data[0:10]
持续错误为:
File "webscraper.py", line 15, in <module>
rows = mydata.findAll(name=None, attrs={}, recursive=True, text=None, limit=None, kwargs='')('tr')
AttributeError: 'NoneType' object has no attribute 'findAll'
根据下面的回答,它现在正在抓取数据,但不是上面要求的格式:
我知道了:
url = 'https://en.m.wikipedia.org/wiki/List_of_largest_Internet_companies'
req = requests.get(url)
bsObj = BeautifulSoup(req.text, 'html.parser')
data = bsObj.find('table',{'class':'wikitable sortable mw-collapsible'})
table_data = []
rows = data.find_all('tr')
for row in rows:
cols = row.find_all('td')
row_data = [ele.text.strip() for ele in cols]
table_data.append(row_data)
# First element is header so that is why it is empty
data=table_data[0:5]
for in in range(5):
rank=data[i]
name=data[i+1]
为了完整性(和完整答案),我希望它显示
-table前五家公司
-公司名称、职级、收入
当前显示为:
维基百科
[[], ['1', 'Amazon', '280.5 美元', '2019', '798,000', '920.22 美元', 'Seattle', '1994', '[1] [2]'], ['2', 'Google', '161.8', '2019', '118,899', '921.14', 'Mountain View', '1998', '[3][4] '], ['3', 'JD.com', '82.8', '2019', '220,000', '51.51', 'Beijing', '1998', '[5][6]'], ['4', 'Facebook', '70.69 美元', '2019', '45,000', '585.37 美元', 'Menlo Park', '2004', '[7][8]']]
['1', 'Amazon', '280.5 美元', '2019', '798,000', '920.22 美元', 'Seattle', '1994', '[1][2]' ]
['2', 'Google', '161.8', '2019', '118,899', '921.14', 'Mountain View', '1998', '[3][4]' ]
通常(并非总是)在处理维基百科表格时,您不必费心 beautifulsoup。只需使用 pandas:
import pandas as pd
table = pd.read_html('https://en.m.wikipedia.org/wiki/List_of_largest_Internet_companies')
table[0]
输出:
Rank Company Revenue ($B) F.Y. Employees Market cap. ($B) Headquarters Founded Refs
0 1 Amazon 0.5 2019 798000 0.22 Seattle 1994 [1][2]
1 2 Google 1.8 2019 118899 1.14 Mountain View 1998 [3][4]
等
然后,您可以使用标准 pandas 方法 select 或删除列等。
编辑:
仅显示前 5 名公司的名称、排名和收入:
table[0][["Rank", "Company","Revenue ($B)"]].head(5)
输出:
Rank Company Revenue ($B)
0 1 Amazon 0.5
1 2 Google 1.8
2 3 JD.com .8
3 4 Facebook .69
4 5 Alibaba .152
这是一个使用 BeautifulSoup 的示例。以下很多内容都是基于这里的答案 .
from bs4 import BeautifulSoup
import requests
url = 'https://en.m.wikipedia.org/wiki/List_of_largest_Internet_companies'
req = requests.get(url)
bsObj = BeautifulSoup(req.text, 'html.parser')
data = bsObj.find('table',{'class':'wikitable sortable mw-collapsible'})
table_data = []
rows = data.find_all('tr')
for row in rows:
cols = row.find_all('td')
row_data = [ele.text.strip() for ele in cols]
table_data.append(row_data)
# First element is header so that is why it is empty
table_data[0:5]
# [[],
# ['1', 'Amazon', '0.5', '2019', '798,000', '0.22', 'Seattle', '1994', '[1][2]'],
# ['2', 'Google', '1.8', '2019', '118,899', '1.14', 'Mountain View', '1998', '[3][4]'],
# ['3', 'JD.com', '.8', '2019', '220,000', '.51', 'Beijing', '1998', '[5][6]'],
# ['4', 'Facebook', '.69', '2019', '45,000', '5.37', 'Menlo Park', '2004', '[7][8]']]
所以隔离这个列表的某些元素,你只需要注意内部列表的数字索引。在这里,让我们看看亚马逊的前几个值。
# The entire row for Amazon
table_data[1]
# ['1', 'Amazon', '0.5', '2019', '798,000', '0.22', 'Seattle', '1994', '[1][2]']
# Rank
table_data[1][0]
# '1'
# Company
table_data[1][1]
# 'Amazon'
# Revenue
table_data[1][2]
# '0.5'
因此,为了仅隔离前几列(排名、公司和收入),您可以 运行 以下列表理解。
iso_data = [tab[0:3] for tab in table_data]
iso_data[1:6]
# [['1', 'Amazon', '0.5'], ['2', 'Google', '1.8'], ['3', 'JD.com', '.8'], ['4', 'Facebook', '.69'], ['5', 'Alibaba', '.152']]
然后,如果你想把它放到一个pandas
数据框中,你可以这样做。
import pandas as pd
# The `1` here is important to remove the empty header
df = pd.DataFrame(table_data[1:], columns = ['Rank', 'Company', 'Revenue', 'F.Y.', 'Employees', 'Market cap', 'Headquarters', 'Founded', 'Refs'])
df
# Rank Company Revenue F.Y. Employees Market cap Headquarters Founded Refs
# 0 1 Amazon 0.5 2019 798,000 0.22 Seattle 1994 [1][2]
# 1 2 Google 1.8 2019 118,899 1.14 Mountain View 1998 [3][4]
# 2 3 JD.com .8 2019 220,000 .51 Beijing 1998 [5][6]
# 3 4 Facebook .69 2019 45,000 5.37 Menlo Park 2004 [7][8]
# 4 5 Alibaba .152 2019 101,958 0.95 Hangzhou 1999 [9][10]
# .. ... ... ... ... ... ... ... ... ...
# 75 77 Farfetch .02 2019 4,532 .51 London 2007 [138][139]
# 76 78 Yelp .01 2019 5,950 .48 San Francisco 1996 [140][141]
# 77 79 Vroom.com .1 2020 3,990 .2 New York City 2003 [142]
# 78 80 Craigslist .0 2018 1,000 - San Francisco 1995 [143]
# 79 81 DocuSign .0 2018 3,990 .62 San Francisco 2003 [144]
#
# [80 rows x 9 columns]
这是另一个,这次只有 beautifulsoup,打印出前 5 家公司的排名、名称和收入:
table_data=[]
trs = soup.select('table tr')
for tr in trs[1:6]:
row = []
for t in tr.select('td')[:3]:
row.extend([t.text.strip()])
table_data.append(row)
table_data
输出:
[['1', 'Amazon', '0.5'],
['2', 'Google', '1.8'],
['3', 'JD.com', '.8'],
['4', 'Facebook', '.69'],
['5', 'Alibaba', '.152']]
初学者 BeautifulSoup,我正在尝试提取
来自此维基百科的公司名称、等级和收入 link。
https://en.m.wikipedia.org/wiki/List_of_largest_Internet_companies
到目前为止我使用的代码是:
from bs4 import BeautifulSoup
import requests
url = "https://en.wikiepdia.org"
req = requests.get(url)
bsObj = BeautifulSoup(req.text, "html.parser")
data = bsObj.find('table',{'class':'wikitable sortable mw-collapsible'})
revenue=data.findAll('data-sort-value')
我意识到甚至 'data' 也不能正常工作,因为当我将它传递到 flask 网站时它没有任何值。
有人可以建议修复和实现上述目标的最优雅的方法,以及一些关于我们在抓取(和格式)时在 HTML 中寻找的最佳方法的建议.
关于这个 link, https://en.m.wikipedia.org/wiki/List_of_largest_Internet_companies 我不确定我要用来提取什么 - table class, div class 或正文 class。此外,如何进一步提取 link 和树下的收入。
我也试过:
data = bsObj.find_all('table', class_='wikitable sortable mw-collapsible')
它运行服务器没有错误。但是,在网页“[]”
上只显示一个空列表基于以下一个答案:我将代码更新为以下内容:
url = "https://en.wikiepdia.org"
req = requests.get(url)
bsObj = BeautifulSoup(req.text, "html.parser")
mydata=bsObj.find('table',{'class':'wikitable sortable mw-collapsible'})
table_data=[]
rows = mydata.findAll(name=None, attrs={}, recursive=True, text=None, limit=None, kwargs='')('tr')
for row in rows:
cols=row.findAll('td')
row_data=[ele.text.strip() for ele in cols]
table_data.append(row_data)
data=table_data[0:10]
持续错误为:
File "webscraper.py", line 15, in <module>
rows = mydata.findAll(name=None, attrs={}, recursive=True, text=None, limit=None, kwargs='')('tr')
AttributeError: 'NoneType' object has no attribute 'findAll'
根据下面的回答,它现在正在抓取数据,但不是上面要求的格式:
我知道了:
url = 'https://en.m.wikipedia.org/wiki/List_of_largest_Internet_companies'
req = requests.get(url)
bsObj = BeautifulSoup(req.text, 'html.parser')
data = bsObj.find('table',{'class':'wikitable sortable mw-collapsible'})
table_data = []
rows = data.find_all('tr')
for row in rows:
cols = row.find_all('td')
row_data = [ele.text.strip() for ele in cols]
table_data.append(row_data)
# First element is header so that is why it is empty
data=table_data[0:5]
for in in range(5):
rank=data[i]
name=data[i+1]
为了完整性(和完整答案),我希望它显示
-table前五家公司 -公司名称、职级、收入
当前显示为:
维基百科
[[], ['1', 'Amazon', '280.5 美元', '2019', '798,000', '920.22 美元', 'Seattle', '1994', '[1] [2]'], ['2', 'Google', '161.8', '2019', '118,899', '921.14', 'Mountain View', '1998', '[3][4] '], ['3', 'JD.com', '82.8', '2019', '220,000', '51.51', 'Beijing', '1998', '[5][6]'], ['4', 'Facebook', '70.69 美元', '2019', '45,000', '585.37 美元', 'Menlo Park', '2004', '[7][8]']]
['1', 'Amazon', '280.5 美元', '2019', '798,000', '920.22 美元', 'Seattle', '1994', '[1][2]' ]
['2', 'Google', '161.8', '2019', '118,899', '921.14', 'Mountain View', '1998', '[3][4]' ]
通常(并非总是)在处理维基百科表格时,您不必费心 beautifulsoup。只需使用 pandas:
import pandas as pd
table = pd.read_html('https://en.m.wikipedia.org/wiki/List_of_largest_Internet_companies')
table[0]
输出:
Rank Company Revenue ($B) F.Y. Employees Market cap. ($B) Headquarters Founded Refs
0 1 Amazon 0.5 2019 798000 0.22 Seattle 1994 [1][2]
1 2 Google 1.8 2019 118899 1.14 Mountain View 1998 [3][4]
等 然后,您可以使用标准 pandas 方法 select 或删除列等。
编辑: 仅显示前 5 名公司的名称、排名和收入:
table[0][["Rank", "Company","Revenue ($B)"]].head(5)
输出:
Rank Company Revenue ($B)
0 1 Amazon 0.5
1 2 Google 1.8
2 3 JD.com .8
3 4 Facebook .69
4 5 Alibaba .152
这是一个使用 BeautifulSoup 的示例。以下很多内容都是基于这里的答案 .
from bs4 import BeautifulSoup
import requests
url = 'https://en.m.wikipedia.org/wiki/List_of_largest_Internet_companies'
req = requests.get(url)
bsObj = BeautifulSoup(req.text, 'html.parser')
data = bsObj.find('table',{'class':'wikitable sortable mw-collapsible'})
table_data = []
rows = data.find_all('tr')
for row in rows:
cols = row.find_all('td')
row_data = [ele.text.strip() for ele in cols]
table_data.append(row_data)
# First element is header so that is why it is empty
table_data[0:5]
# [[],
# ['1', 'Amazon', '0.5', '2019', '798,000', '0.22', 'Seattle', '1994', '[1][2]'],
# ['2', 'Google', '1.8', '2019', '118,899', '1.14', 'Mountain View', '1998', '[3][4]'],
# ['3', 'JD.com', '.8', '2019', '220,000', '.51', 'Beijing', '1998', '[5][6]'],
# ['4', 'Facebook', '.69', '2019', '45,000', '5.37', 'Menlo Park', '2004', '[7][8]']]
所以隔离这个列表的某些元素,你只需要注意内部列表的数字索引。在这里,让我们看看亚马逊的前几个值。
# The entire row for Amazon
table_data[1]
# ['1', 'Amazon', '0.5', '2019', '798,000', '0.22', 'Seattle', '1994', '[1][2]']
# Rank
table_data[1][0]
# '1'
# Company
table_data[1][1]
# 'Amazon'
# Revenue
table_data[1][2]
# '0.5'
因此,为了仅隔离前几列(排名、公司和收入),您可以 运行 以下列表理解。
iso_data = [tab[0:3] for tab in table_data]
iso_data[1:6]
# [['1', 'Amazon', '0.5'], ['2', 'Google', '1.8'], ['3', 'JD.com', '.8'], ['4', 'Facebook', '.69'], ['5', 'Alibaba', '.152']]
然后,如果你想把它放到一个pandas
数据框中,你可以这样做。
import pandas as pd
# The `1` here is important to remove the empty header
df = pd.DataFrame(table_data[1:], columns = ['Rank', 'Company', 'Revenue', 'F.Y.', 'Employees', 'Market cap', 'Headquarters', 'Founded', 'Refs'])
df
# Rank Company Revenue F.Y. Employees Market cap Headquarters Founded Refs
# 0 1 Amazon 0.5 2019 798,000 0.22 Seattle 1994 [1][2]
# 1 2 Google 1.8 2019 118,899 1.14 Mountain View 1998 [3][4]
# 2 3 JD.com .8 2019 220,000 .51 Beijing 1998 [5][6]
# 3 4 Facebook .69 2019 45,000 5.37 Menlo Park 2004 [7][8]
# 4 5 Alibaba .152 2019 101,958 0.95 Hangzhou 1999 [9][10]
# .. ... ... ... ... ... ... ... ... ...
# 75 77 Farfetch .02 2019 4,532 .51 London 2007 [138][139]
# 76 78 Yelp .01 2019 5,950 .48 San Francisco 1996 [140][141]
# 77 79 Vroom.com .1 2020 3,990 .2 New York City 2003 [142]
# 78 80 Craigslist .0 2018 1,000 - San Francisco 1995 [143]
# 79 81 DocuSign .0 2018 3,990 .62 San Francisco 2003 [144]
#
# [80 rows x 9 columns]
这是另一个,这次只有 beautifulsoup,打印出前 5 家公司的排名、名称和收入:
table_data=[]
trs = soup.select('table tr')
for tr in trs[1:6]:
row = []
for t in tr.select('td')[:3]:
row.extend([t.text.strip()])
table_data.append(row)
table_data
输出:
[['1', 'Amazon', '0.5'],
['2', 'Google', '1.8'],
['3', 'JD.com', '.8'],
['4', 'Facebook', '.69'],
['5', 'Alibaba', '.152']]