2-4 基于 HTML 的爬虫,Python(Beautifulsoup)实现(版本:py3)

安装 BeatifulSoup

进入你创建的环境,比如课程中是执行activate course_py35进入之前创建的 course_py35 这个环境

可以通过 pip 来安装BeautifulSoup4 
pip install beautifulsoup4 
 

Jupyter 中实现网页的获取

运行以下代码看BeautifulSoup 是否正常安装(若未提示错误则表示正常) 
from bs4 import BeautifulSoup 
  
输入课程中的示例网页代码:

html_doc = """ <html><head><title>The Dormouse's story</title></head> <body> <p class="title"><b>The Dormouse's story</b></p> <p class="story">Once upon a time there were three little sisters; and their names were <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>, <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>; and they lived at the bottom of a well.</p> <p class="story">...</p> """

  
使用BeautifulSoup解析HTML文档 
soup = BeautifulSoup(html_doc,‘html.parser’) 
“html_doc”表示这个文档名称,在上面的代码中已经定义,“html_parser”是解析网页所需的解析器,所以使用BeautifulSoup解析HTML文档的一般格式为soup=BeautifulSoup(网页名称,'html.parser') 
  
用 soup.prettify 打印网页 
print(soup.prettify()) 
BeautifulSoup 中 “soup.prettify” 这个方法可以让网页更加友好地打印出来

  
BeautifulSoup 解析网页的一些基本操作

在 BeautifulSoup 中,通过soup.……的形式来调用一个方法 
soup.title:返回title部分的全部内容 <title>The Dormouse's story</title>

soup.title.name:返回title标签的名称'title'

soup.title.string:返回这个标签的内容"The Dormouse's story"

soup.find_all(‘a’):返回所有超链接的元素如下: 
<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>, 
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, 
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

soup.find(id="link3"):返回 id=link3 部分的内容,如下: 
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

爬取“NATIONAL WEATHER”的天气数据

课程示例的旧金山天气页面地址为:

http://forecast.weather.gov/MapClick.php?lat=37.77492773500046&lon=-122.41941932299972#.WUnSFhN95E4

可以在浏览器提供的开发者工具中查看代码:更多工具 > 开发者工具

  
1.通过url.request 返回网页内容

import urllib.request as urlrequest
weather_url='http://forecast.weather.gov/MapClick.php?lat=37.77492773500046&lon=-122.41941932299972'
web_page=urlrequest.urlopen(weather_url).read()
print(web_page)

  
2.通过 BeautifulSoup 来抓取网页中的天气信息

from bs4 import BeautifulSoup
soup=BeautifulSoup(web_page,'html.parser')
print(soup.find(id='seven-day-forecast-body').get_text())

当然,你可以通过prettify输出一个美观的网页代码

from bs4 import BeautifulSoup
soup=BeautifulSoup(web_page,'html.parser')
print(soup.find(id='seven-day-forecast-container').prettify())

  
3.将天气数据完整有序地抽取出来

soup_forecast=soup.find(id='seven-day-forecast-container')
date_list=soup_forecast.find_all(class_='period-name')
desc_list=soup_forecast.find_all(class_='short-desc')
temp_list=soup_forecast.find_all(class_='temp')
for i in range(9):
    date=date_list[i].get_text()
    desc=desc_list[i].get_text()
    temp=temp_list[i].get_text()
    print("{}{}{}".format(date,desc,temp))

  
综合上述,这个简单爬虫的完整代码如下,注意每个步骤的作用

#导入需要的包和模块,这里需要的是 urllib.request 和 Beautifulsoup
import urllib.request as urlrequest
from bs4 import BeautifulSoup

#通过urllib来获取我们需要爬取的网页
weather_url='http://forecast.weather.gov/MapClick.php?lat=37.77492773500046&lon=-122.41941932299972'
web_page=urlrequest.urlopen(weather_url).read()

#用 BeautifulSoup 来解析和获取我们想要的内容块
soup=BeautifulSoup(web_page,'html.parser')
soup_forecast=soup.find(id='seven-day-forecast-container')

#找到我们想要的那一部分内容
date_list=soup_forecast.find_all(class_='period-name')
desc_list=soup_forecast.find_all(class_='short-desc')
temp_list=soup_forecast.find_all(class_='temp')

#将获取的内容更好地展示出来,用for循环来实现
for i in range(9):
    date=date_list[i].get_text()
    desc=desc_list[i].get_text()
    temp=temp_list[i].get_text()
    print("{}{}{}".format(date,desc,temp))

  
 

完成一个作业

  
将电影《摔跤吧,爸爸》的豆瓣评分抓取下来。

参考代码如下:题目很简单,务必先自己练习。

import urllib.request as urlrequest
from bs4 import BeautifulSoup

douban_url='https://movie.douban.com/subject/26387939/'
page=urlrequest.urlopen(douban_url).read()

soup=BeautifulSoup(page,'html.parser')
score=soup.find(class_='ll rating_num').get_text()

print(score)

也许你也可以尝试去抓取电影的基本信息,海报等等。




 

补充知识

1.解析HTML网页

不同于API爬取得到的是JSON 格式的数据,需要用到JSON库来处理,基于网页的爬虫返回的HTML页面需要用BeautifulSoup库来解析。

BeautifulSoup解析HTML

BeautifulSoup库的主要功能是:

  • 通过find函数,利用tag来返回相应的代码块
  • 通过prettify函数,可以友好地打印HTML网页
  • 使用next&previous函数寻求上下文的tag

help函数 
在遇见一个陌生的Python库时,第一个就是查看帮助信息,调用help函数,如help(BeautifulSoup)就可以调出帮助信息,通过help文档你可以看到BeautifulSoup库中各种函数的详细用法。

链接材料

学有余力的话,请阅读BeautifulSoup官方文档,如果能够独立操作这个文档的所有内容,相信你在爬虫高手这条路上已经甩开大部分人啦。

2.format函数

仔细阅读课后复习材料,你会注意到print("{}{}{}".format(date,desc,temp))这样一个表达式,用format函数串联起三个字符串,format函数在Python中的作用巨大,请阅读Python的format函数

format函数可以操作字符串的强大函数,本质是将被操作对象当做一个模板,并更改传入的参数

{}:表示预留的位置 
format.():括号里表示需要传递的字符串 
位置、关键字参数、对象属性、下标来进行参数的传递。

示例:

c = "{0}{1}".format("hello","world!")
print(c)

url = "http://www.pkbigdata.com"
sub = "/common/cmptIndex.html"
web = "{0}{1}".format(url,sub)
print(web)

输入以上代码,你将得到hello word的输出和url网址的输出,在连续爬取多个网页的信息时,这个函数就可以实现url地址的变化。

跟着链接中的内容进行操作,你需要掌握以下内容:

  • 使用format函数进行参数的映射
  • 调整输出的格式(精度、填充、对齐等格式)

扩展阅读

解析HTML还有一个重要的工具---正则表达式,学有余力的你可以尝试用不同的方法解析HTML。

正则表达式解析HTML

正则表达式 
正则表达式的原理是依次拿出表达式和文本中的字符进行比较,并有其匹配的规则,例如最简单的有:

.可以匹配任意字符 
\d用于匹配任意的数字 
那么.\d就可以用于匹配a1

这里使用到的是re库,常用于解析HTML的函数有re.match,re.search等等。示例:

import re
url = "http://www.baidu.com"
w = "www."
m = re.search(w,url)
if m:
    print(m.group())
if m == False:
    print('cannot match')
#返回:www.

爬虫返回的html页面也是字符串类型,使用re库函数,可以用正则表达式来匹配。

链接材料

也许你并不能在短时间内记忆正则表达式的大部分使用方法,这也不是这门课程的必学内容,但请你掌握正则表达式的大致思想,在今后遇见特定的场合,可以马上回想起正则表达式是如何支持你预想的操作。

学习完正则表达式之后,是否觉得BeautifulSoup 包十分方便可爱呢,的确在解析HTML网页方面,使用BeautifulSoup库进行解析是十分方便的,正则表达式主要自己编写,但在处理纯文本数据的时候,正则表达式就十分灵活。

恭喜你!你已经完成2.4节补充材料的阅读。现在可以选择重复阅读,或者进入到下一环节。

猜你喜欢

转载自blog.csdn.net/feng_jlin/article/details/82182203
2-4