一、实验目的与要求
1、了解利用Python语言爬取网络数据并提取关键信息的技术和方法。
2、学习和掌握定向网络数据爬取和网页解析的基本能力。
3、了解Python计算生态中最优秀的网络数据爬取和解析技术。
二、实验原理
获取网络数据的方式很多,常见的是先抓取网页数据(这些数据是html或其它格式的网页源代码),再进行网页数据解析,而有的网站则直接提供了数据文件供下载,还有的网站提供了Web API供用户使用。后两种方式一般能获得直接的数据,不需要再进行解析。
1、网页抓取
网络数据获取也称为爬取。爬取网络数据通常分为两个阶段,第一阶段是网页抓取;第二个阶段是网页数据解析。网页抓取可使用Python的urllib内建模块,其中的requests模块可以方便地抓取网页。主要知识点有:(1)Requests库基本使用;(2)Robots协议;(3)搜索引擎关键词查询接口;(4)网络数据解析。
2、Beautiful Soup库
(1)Beautiful Soup基础:Beautiful Soup是一个可以从HTML或XML文件中提取数据的Python库,与Requests库一样,Beautiful Soup的官网文档资源也十分丰富;(2)Beautiful Soup的使用。(略)
3、re正则表达式
(1)正则表达式简介:在编写处理字符串的程序和网页或搜索网页时常常要查找符合某些复杂模式/规则的字符串,正则表达式就是用来描述这些规则的工具;(2)re正则表达式模块:在Python中有re模块支持正则表达式。re模块中使用最多的是findall()函数,其一般形式为:findall(pattern,string)
4、用Web API获取数据
利用面向开发者的开放接口(API)可以更快速、简单且集中地获取数据,并且它们大多已为直接的数据而不需要再另外解析。
三、预习与准备
1、提前预习Python关于网络数据获取的基础语法知识,实验之前编写好程序代码,程序均在Python 3.X环境中运行。
2、练习Python网络数据获取的常见编程技巧。提前熟悉requests库抓取网页的基本方法及Robots协议,熟悉Beautiful Soup库解析网页数据的基本方法,了解利用搜索引擎关键词查询接口抓取网页的方法,了解正则表达式re模块解析网页数据最基本的使用以及Web API获取网络数据的方法。
编程前需要在操作系统终端使用pip命令安装Requests库、Beautiful Soup库:pip install requests,pip install beautifulsoup4,其它类似。
在pycharm中安装第三方库Requests、BeautifulSoup4等:
(1)打开pycharm软件,点击file-setting
(2)在目录下点击Project Interpreter,在目录的右侧,点击右上方的+
(3)在输入框中输入requests,点击安装(提示sucessful时,表名安装第三方库成功),在pycharm中安装其他第三方库是一样的步骤。
实验题1 通过在360搜索中进行关键词查询确定其关键词查询接口,利用requests库的get()函数抓取关键词“Python字典”搜索结果网页,用statue_code检查响应结果的状态码是否正常或输出响应结果的前500字节进行检测。
提示:通过在360搜索中利用关键词进行搜索可确定其关键词查询接口为http://www.so.com/s?q=%s,因此只要将kw={'q': 'Python 字典'}作为requests库get()函数params参数的实参即可抓取到需要的搜索结果页面。
源码:
import requests
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
kw = {'q': 'Python 字典'}
r = requests.get("http://www.so.com/s?q",params=kw,headers=headers)
r.raise_for_status()
print(r.text)
except Exception as e:
print(e)
实验题2 在“http://money.cnn.com/data/dow30/”上抓取道指成分股数据并解析其中30家公司的代码、公司名称和最近一次成交价,将结果放到一个列表中输出。
提示:首先利用requests库的get()函数抓取网页,30家公司的代码、公司名称和最近一次成交价在网页源代码中有较为明显的特征,每一组需要数据的前后都有固定的字符串,因此可以写出如下模式:
'class="wsod_symbol">(.*?)<\/a>.*<span.*">(.*?)<\/span>.*\n.*class="wsod_stream">(.*?)<\/span>'
再利用re模块中的findall()函数即可解析出需要的数据。
源码:
import requests
import re
r = requests.get("https://money.cnn.com/data/dow30/") #爬取网页内容
reg = re.compile('class="wsod_symbol">(.*?)<\/a>.*?<span.*?">(.*?)<\/span>.*?\n.*?class="wsod_stream">(.*?)<\/span>') #预编译正则表达式
ans = re.findall(reg, r.text) #利用正则表达式解析内容
print("%-7s%-20s%-10s" % ('Code','Name','Prize')) #占位输出
for key in ans:
print("%-7s%-20s%-10s" % (key[0],key[1],key[2]))
实验题3 抓取豆瓣读书中对某本书的前50条短评内容并计算星级评定分数的平均值(保留两位小数)。
提示:本题要求寻找前50个短评,所以需要抓取的页面不止一个。经过观察发现,同一本书的短评网页虽然可能有多页,但它们的url是有规律的,例如url的最后“p=”后的数字是有序的,因此可通过“共同的url+str(i)”这样的方式进行多个页面的循环抓取。另外,因为只要抓取前50个短评,所以可定义一个用于计数的变量,即当变量值达到50时,用break语句跳出循环。除此之外,还要考虑因为是抓取多个页面,所以要遵循其网站Robots协议进行延时。延时可利用time模块中的sleep()函数,例如time.sleep(5)。
源码:
import re, time
import requests
from bs4 import BeautifulSoup
count = 0
i = 0
s, count_s, count_del = 0, 0, 0
lst_stars = []
url = 'https://book.douban.com/subject/1456692/comments/hot?p='
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
while count < 50: # 少于50就循环
try:
r = requests.get(url + str(i + 1),headers=headers)
except Exception as err:
print(err)
break
soup = BeautifulSoup(r.text, 'lxml')
comments = soup.find_all('span', 'short') # 得到评论
pattern = re.compile('<span class="user-stars allstar(.*?) rating"') # 得到分数
p = re.findall(pattern, r.text)
for item in comments: # 打印爬下来的当前页的所有评论
count += 1 # 每得到一条评论,序号加1
if count > 50:
count_del += 1 # 如果超过50,count_del加1,打不打印评论
else:
print(count, item.string) # 打印序号,评论内容
for star in p:
lst_stars.append(int(star)) # 将当前页得到的分数放入列表lst_stars
time.sleep(5) # 根据robots.txt协议,间隔5秒
i += 1
for star in lst_stars[:-count_del]:
s += int(star)
if count >= 50:
print(s // (len(lst_stars) - count_del))
实验题4 利用豆瓣电影API(参考url:https://developers.douban.com/wiki/?title = movie_v2,注意要遵循其API权限规定)获取ID是1291546的电影条目信息,输出其评分的平均值和电影的中文名。(选做)
提示:用get()函数获得的数据是JSON格式的,需要先解码(data=r.json()),然后对结果进行具体细节内容的查询,方法与字典类似,最后的结果是电影《霸王别姬》,评分的平均值为9.5。
源码:
import requests
import json
basedUrl = "https://douban.uieee.com"
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
url = basedUrl+'/v2/movie/top250'
params = {
"start":"1",
"count":"20" } r = requests.get(url,params=params,headers=headers) data = r.json() total = data['total'] #print(data) # 创建存储title和score的空列表 in_theaters = [] for i in range(20): title = data['subjects'][i]['title'] score = data['subjects'][i]['rating']['average'] genres = data['subjects'][i]['genres'] name = data['subjects'][i]['casts'][0]['name'] in_theaters.append((title, score, genres, name)) # 按电影分数从高到底排序 in_theaters.sort(key=lambda score: score[1], reverse=True) for (title,score,genres,name) in in_theaters: print("电影名:{},评分:{}".format(title,score)) except Exception as e: print(e)
五、实验结论(或总结)
总体来说都还算ok的,本人具有较强的爬虫技术,所以本次章节比较简单!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。