使用Python / BeautifulSoup刮网站 - 为什么这个表返回None?

时间:2018-03-09 00:15:44

标签: python html web-scraping beautifulsoup

我正在尝试从此表中删除数据:: http://www.worldlifeexpectancy.com/cause-of-death/alzheimers-dementia/by-country/ 我试图找到的元素是该国家的名称,在本例中为芬兰:

<table cellspacing="0" align="center" class="hc_tbl">
<tbody>
<tr>
<td class="hc_name" style="background-color: transparent;">Finland</td>

以下是我使用的代码:

res = requests.get('http://www.worldlifeexpectancy.com/cause-of-death/alzheimers-dementia/by-country/')

soup = BeautifulSoup(res.content, 'html5lib')

table = soup.find('table', {'class': 'hc_tbl'})

for row in table.find('tbody').find_all('tr'):
    name = row.find('td', {'class':'hc_name'}).text.strip()
    print (name)

然而,这会产生一个错误,表示“无类型”&#39;对象没有属性&#39; find&#39; ;;所以看起来表元素被返回为&#39;无&#39;。

我已经阅读了其他似乎有类似问题的帖子,但在这种情况下没有一个修复工作。

非常感谢任何想法

谢谢

2 个答案:

答案 0 :(得分:1)

通过在发送请求时检查网站的来源,可以看出网站是动态的。因此,最好使用浏览器操作工具,例如selenium

from bs4 import BeautifulSoup as soup 
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get('http://www.worldlifeexpectancy.com/cause-of-death/alzheimers-dementia/by-country/')
countries = filter(None, [i.text for i in soup(driver.page_source, 'lxml').find_all('td', {'class':'hc_name'})])

输出:

[u'Finland', u'Djibouti', u'North Korea', u'United States', u'Gabon', u'Venezuela', u'Canada', u'Estonia', u'Zambia', u'Iceland', u'Guyana', u'Russia', u'Sweden', u'Senegal', u'Burundi', u'Switzerland', u'Jordan', u'Eritrea', u'Norway', u'Mali', u'Central Africa', u'Denmark', u'Namibia', u'DR Congo', u'Netherlands', u'Romania', u'Somalia', u'Belgium', u'Moldova', u'Pakistan', u'Spain', u'Bahrain', u'Bolivia', u'Australia', u'Panama', u'Tunisia', u'France', u'Ghana', u'Bhutan', u'United Kingdom', u'Mexico', u'Syria', u'Cuba', u'Sierra Leone', u'Turkey', u'Chile', u'Mauritania', u'Nicaragua', u'Uruguay', u'Tanzania', u'Egypt', u'Israel', u'Sri Lanka', u'Madagascar', u'New Zealand', u'Poland', u'Bosnia/Herzeg.', u'Ireland', u'Benin', u'Lebanon', u'Italy', u'Mozambique', u'Ethiopia', u'Hungary', u'Belize', u'Nepal', u'Malta', u'Nigeria', u'Guatemala', u'Luxembourg', u'Montenegro', u'Ukraine', u'Germany', u'Angola', u'Paraguay', u'Brazil', u'Gambia', u'Colombia', u'South Korea', u'Uganda', u'Bangladesh', u'Cyprus', u'New Guinea', u'Saudi Arabia', u'Costa Rica', u'Slovakia', u'Philippines', u'Iran', u'Guinea-Bissau', u'Indonesia', u'South Africa', u'Burkina Faso', u'Slovenia', u'Austria', u'Cote d Ivoire', u'Honduras', u'Serbia', u'Chad', u'Armenia', u'Trinidad/Tob.', u'Morocco', u'Peru', u'Bahamas', u'Comoros', u'Thailand', u'Maldives', u'Guinea', u'El Salvador', u'Portugal', u'Kenya', u'Yemen', u'Latvia', u'Greece', u'Myanmar', u'Czech Republic', u'Zimbabwe', u'Bulgaria', u'Argentina', u'Viet Nam', u'Turkmenistan', u'Qatar', u'Belarus', u'Malaysia', u'Solomon Isl.', u'Kazakhstan', u'Macedonia', u'Croatia', u'Rwanda', u'Laos', u'Swaziland', u'Niger', u'Mongolia', u'Arab Emirates', u'Togo', u'Timor-Leste', u'Fiji', u'Dominican Rep.', u'Afghanistan', u'Haiti', u'South Sudan', u'Kuwait', u'Equ. Guinea', u'Malawi', u'Azerbaijan', u'Cape Verde', u'Ecuador', u'India', u'Lesotho', u'Brunei', u'Cambodia', u'Jamaica', u'Congo', u'Tajikistan', u'Botswana', u'Albania', u'Kyrgyzstan', u'China', u'Sudan', u'Uzbekistan', u'Barbados', u'Oman', u'Georgia', u'Iraq', u'Mauritius', u'Singapore', u'Lithuania', u'Algeria', u'Suriname', u'Cameroon', u'Liberia', u'Japan', u'Libya']

答案 1 :(得分:0)

该表格在页面源中不可用。它使用AJAX请求动态加载。如果您查看开发人员工具下的Network标签,则会向此网址发送AJAX请求 - http://www.worldlifeexpectancy.com/j/country-cause?cause=95&order=hight

您可以看到数据以JSON格式提供。您可以在内置requests函数的帮助下仅使用.json()模块来抓取此数据。

您可以从此JSON数据中获取所有数据,例如排名,国家/地区和费率。

import requests

r = requests.get('http://www.worldlifeexpectancy.com/j/country-cause?cause=95&order=hight')
data = r.json()

for row in data['chart']['countries']['countryitem']:
    id_ = row['id']
    country = row['name']
    rank = row['rank']
    value = row['value']
    print(rank, id_, country, value)

部分输出:

1 FI Finland 53.77
2 US United States 45.58
3 CA Canada 35.50
4 IS Iceland 34.08
5 SE Sweden 32.41
6 CH Switzerland 32.25
...
...

另外,请记住页面源中永远不会提供<tbody>元素。浏览器插入它。因此,在抓桌时,请勿在{{1​​}}函数中使用tbody。请参阅Why do browsers insert tbody element into table elements?