Python与网页处理

Python 语言发展中有一个里程碑式的应用事件,即美国谷歌(GOOGLE)公司在搜索引擎后端采用Python 语言进行链接处理和开发,这是该语言发展成熟的重要标志。Python 语言的简洁性和脚本特点非常适合链接和网页处理。万维网(WWW)的快速发展带来了大量获取和提交网络信息的需求,这产生了“网络爬虫”等一系列应用。

Python 语言提供了很多类似的函数库,包括urllib、urllib2、urllib3、wget、scrapy、requests 等。对于爬取回来的网页内容,可以通过re(正则表达式)、beautifulsoup4等函数库来处理。网络爬虫一般分为两个步骤:(1)通过网络连接获取网页内容(2)对获得的网页内容进行处理。分别使用两个不同的函数库:requests 和beautifulsoup4,它们都是第三方库。

安装第三方库

安装requests库命令: pip install requests 或者 pip3 install requests

安装beautifulsoup4库: pip install beautifulsoup4  或者 pip3 install beautifulsoup4

网页爬虫

python语言实现网页爬虫和提交信息很简单,代码量少,且无需知道网络通信方面知识,非专业者也可以容易上手。但是,肆意的爬取网页容易触碰法律的底线,所以在爬取一个网站前最好先康康这个网页的Robots排除协议(爬虫协议),它是网站管理者表达是否希望爬虫自动获取网络信息意愿的方法,一般在网页后加上 /robots.txt 即可康到。

Robots 排除协议重点约定不希望爬虫获取的内容,如果没有该文件则表示网站内容可以被爬虫获得,然而,Robots 协议不是命令和强制手段,只是国际互联网的一种通用道德规范。绝大部分成熟的搜索引擎爬虫都会遵循这个协议,建议个人也能按照互联网规范要求合理使用爬虫技术

B站爬虫协议

requests库的使用

requests 库是一个简洁且简单的处理HTTP请求的第三方库,最大的优点是程序编写过程更接近正常URL 访问过程,这个库建立在Python 语言的urllib3 库基础上。

request 库支持非常丰富的链接访问功能,包括:国际域名和URL 获取、HTTP 长连接和连接缓存、HTTP 会话和Cookie 保持、浏览器使用风格的SSL 验证、基本的摘要认证、有效的键值对Cookie 记录、自动解压缩、自动内容解码、文件分块上传、HTTP(S)代理功能、连接超时处理、流数据下载等。详见 http://docs.python‐requests.org。

requests库中的网页请求函数

get() 函数是获取网页最常用的方式,在调用 requests.get() 函数后,返回的网页内容会保存为一个Response 对象,其中,get() 函数的参数url 必须链接采用 HTTP 或 HTTPS 方式访问

import requests
# get方式打开B站
request = requests.get("http://www.bilibili.com")
print(type(request))  # <class 'requests.models.Response'>

和浏览器的交互过程一样,requests.get() 代表请求过程,它返回的 response 对象代表响应。返回内容作为一个对象更便于操作,Response 对象的属性如下表所示,需要采用<a>.<b>

response对象属性

status_code 属性返回请求HTTP 后的状态,在处理数据之前要先判断状态情况,如果请求未被响应,需要终止内容处理。

text 属性是请求的页面内容,以字符串形式展示。

encoding 属性非常重要,它给出了返回页面内容的编码方式,可以通过对encoding 属性赋值更改编码方式,以便于处理中文字符

content 属性是页面内容的二进制形式

import requests
# response对象属性代码演示
request = requests.get("http://www.baidu.com")  # 使用 get方法打开百度链接
print(request.status_code)  # 返回状态(200)
print(request.text)  # 观察返回的内容,中文字符是否能正常展示(不能)
print(request.encoding)  # 默认的编码方式是IS0-8859-1,所以中文是乱码(ISO-8859-1)
request.encoding = 'utf-8'  # 更加编码方式为utf-8
print(request.text)  # 更改完成,中文字符能显示了

response对象的方法

json() 方法能够在HTTP 响应内容中解析存在的JSON 数据,这将带来解析HTTP的便利

raise_for_status() 方法能在非成功响应后产生异常,即只要返回的请求状态status_code 不是200,这个方法会产生一个异常,用于try…except 语句。使用异常处理语句可以避免设置一堆复杂的if 语句,只需要在收到响应调用这个方法,就可以避开状态字200 以外的各种意外情况。

requests 中的常见异常:当遇到网络问题时,如:DNS 查询失败、拒绝连接等,requests 会抛出ConnectionError 异常;遇到无效HTTP 响应时,requests 则会抛出HTTPError 异常;若请求url 超时,则抛出Timeout 异常;若请求超过了设定的最大重定向次数,则会抛出一个TooManyRedirects 异常...

import requests# 获取网页源码
def askUrl(url):try:response = requests.get(url, timeout=30)response.raise_for_status()  # 如果状态码不是200, 引发异常response.encoding = 'utf-8'  # 防止中文乱码return response.textexcept:return ''

beautifulsoup4库的使用

beautifulsoup4 库,也称为Beautiful Soup 库或bs4 库,是一个解析和处理HTML 和XML 的第三方库,但需要注意,它不是BeautifulSoup 库。它的最大优点是能根据HTML 和XML 语法建立解析树,进而高效解析其中的内容。使用requests 库获取HTML 页面并将其转换成字符串后,需要进一步解析HTML页面格式,提取有用信息,这时就需要处理HTML 和XML 的函数库。

HTML 建立的Web 页面一般非常复杂,除了有用的内容信息外,还包括大量用于页面格式的元素,直接解析一个Web 网页需要深入了解HTML 语法,而且比较复杂。beautifulsoup4 库将专业的Web 页面格式解析部分封装成函数,提供了若干有用且便捷的处理函数。beautifulsoup4 库采用面向对象思想实现,简单说,它把每个页面当做一个对象,通过<a>.<b>的方式调用对象的属性(即包含的内容),或者通过<a>.<b>()的方式调用方法(即处理函数)。

更多相关介绍请参考第三方库主页 http://www.crummy.com/software/BeautifulSoup/bs4/

import requests
from bs4 import BeautifulSoup
# 创建一个BeautifulSoup对象
request = requests.get('http://www.baidu.com')
request.encoding = 'utf-8'  # 方便演示,暂且不管异常
soup = BeautifulSoup(request.text)
print(type(soup))  # <class 'bs4.BeautifulSoup>'

创建的BeautifulSoup 对象是一个树形结构,它包含HTML 页面里的每一个Tag(标签)元素,如<head>、<body>等。具体来说,HTML 中的主要结构都变成了BeautifulSoup 对象的一个属性,可以直接用<a>.<b>形式获得,其中<b>的名字采用HTML 中标签的名字。

BeautifulSoup对象的常用属性
# BeautifulSoup对象的常用属性
print(soup.head)
# <head><meta content="text/html;charset=utf-8" http-equiv="content-type"/><meta content="IE=Edge" http-equiv="X-UA-Compatible"/><meta content="always" name="referrer"/><link href="http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css" rel="stylesheet" type="text/css"/><title>百度一下,你就知道</title></head>
print(soup.title)
# <title>百度一下,你就知道</title>
print(type(soup.title))
# <class 'bs4.element.Tag'>
print(soup.p)
# <p id="lh"> <a href="http://home.baidu.com">关于百度</a> <a href="http://ir.baidu.com">About Baidu</a> </p>

每一个Tag 标签在beautifulsoup4 库中也是一个对象,称为Tag 对象。上例中,title 是一个标签对象。每个标签对象在HTML 中都有类似的结构: <a href="//www.bilibili.com/v/channel" target="_blank"> 其中,尖括号(<>)中的标签的名字是name,尖括号内其他项是attrs,尖括号之间的内容是string。因此,可以通过Tag 对象的name、attrs 和string 属性获得相应内容,采用<a>.<b>的语法形式。

标签Tag 有 4 个常用属性

Tag  4 个常用属性
# Tag  4 个常用属性
print(soup.a)
# <a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻</a>
print(soup.a.name)
# a
print(soup.a.attrs)
# {'href': 'http://news.baidu.com', 'name': 'tj_trnews', 'class': ['mnav']}
print(soup.a.contents)
# ['新闻']
print(soup.a.string)
# 新闻

由于HTML 语法可以在标签中嵌套其他标签,所以,string 属性的返回值遵循如下原则:

  1. 如果标签内部没有其他标签,string 属性返回其中的内容;
  2. 如果标签内部有其他标签,但只有一个标签,string 属性返回最里面标签的内容;
  3. 如果标签内部有超过1 层嵌套的标签,string 属性返回None(空字符串)。

HTML 语法中同一个标签会有很多内容,例如<a>标签,百度首页一共有11 处,直接调用soup.a 只能返回第一个。当需要列出标签对应的所有内容或者需要找到非第一个标签时,需要用到 BeautifulSoup 的 find() 和 find_all() 方法。这两个方法会遍历整个 HTML 文档,按照条件返回标签内容。

find_all() 方法

find()方法
# 查找对应标签a = soup.find_all('a')
print(len(a))
# 11print(a)
# [<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻</a>, <a class="mnav" href="http://www.hao123.com" name="tj_trhao123">hao123</a>, <a class="mnav" href="http://map.baidu.com" name="tj_trmap">地图</a>, <a class="mnav" href="http://v.baidu.com" name="tj_trvideo">视频</a>, <a class="mnav" href="http://tieba.baidu.com" name="tj_trtieba">贴吧</a>, <a class="lb" href="http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1" name="tj_login">登录</a>, <a class="bri" href="//www.baidu.com/more/" name="tj_briicon" style="display: block;">更多产品</a>, <a href="http://home.baidu.com">关于百度</a>, <a href="http://ir.baidu.com">About Baidu</a>, <a href="http://www.baidu.com/duty/">使用百度前必读</a>, <a class="cp-feedback" href="http://jianyi.baidu.com/">意见反馈</a>]print(soup.find_all('a', {'name': 'tj_trhao123'}))
# [<a class="mnav" href="http://www.hao123.com" name="tj_trhao123">hao123</a>]import re   # 利用正则进行匹配print(soup.find_all('a', {'name': re.compile('hao')}))
# [<a class="mnav" href="http://www.hao123.com" name="tj_trhao123">hao123</a>]print(soup.find_all(string=re.compile('百度')))
# ['百度一下,你就知道', '关于百度', '使用百度前必读']

简单说,BeautifulSoup 的 find_all() 方法可以根据标签名字、标签属性和内容检索并返回标签列表,通过片段字符串检索时需要使用正则表达式re 函数库,re 是Python 标准库,直接通过import re 即可使用。采用 re.compile('xxx') 实现对片段字符串(如'hao')的检索。当对标签属性检索时,属性和对应的值采用JSON格式,例如: 'name':re.compile('hao')  其中,键值对中值的部分可以是字符串或者正则表达式。正则表达式的使用这里不介绍。

除了find_all()方法,BeautifulSoup 类还提供一个find()方法,它们的区别只是前者返回全部结果而后者返回找到的第一个结果,find_all()函数由于可能返回更多结果,所以采用列表形式;find()函数返回字符串形式。

处理网页需要对HTML 有一定的理解,然而实现爬虫就不算复杂,这里仅介绍beautifulsoup4 库中与爬虫相关的一些属性和操作。详细深入使用还请参考 https://beautifulsoup.cn/。

实例:中国大学排名爬虫

大学排名爬虫的构建需要三个重要步骤:

第一,从网络上获取网页内容;

第二,分析网页内容并提取有用数据到恰当的数据结构中;

第三,利用数据结构展示或进一步处理数据。

中国大学排名网址: https://www.shanghairanking.cn/rankings/bcur/2021

导入相应包

import requests
from bs4 import BeautifulSoup
import xlwt

从网页上获取网页内容,并进行异常处理

# 访问相应网址, 返回 utf-8 编码的 HTML 源代码
def askUrl(url):try:r = requests.get(url, timeout=30)r.raise_for_status()  # 如果状态不是200,引发异常r.encoding = 'utf-8'  # 无论原来用什么编码,都改成utf-8return r.textexcept:return ''

网页源代码(部分)

通过观察源代码,可以发现每个大学排名的数据信息被封装在一个<tr></tr>之间的结构中。这是HTML 语言表示表格中一行的标签,在这行中,每列内容采用<td></td>表示。以“清华大学”为例,它对应一行信息的HTML 代码如下:

清华大学源代码(部分)

这个代码中每个td 标签包含大学排名表格的一个列数值,与表头一一对应。因此,如果要获得其中的数据,需要首先找到<tr></tr>标签,并遍历其中每个<td></td>标签,获取其值写入程序的数据结构中,这个代码封装成函数表示如下:

# 处理 HTML 源代码,返回爬取的数据
def getData(html):soup = BeautifulSoup(html, 'lxml')Tr = soup.find_all('tr')allUniversity = []for tr in Tr:Td = tr.find_all('td')if len(Td) == 0:continuesingleUniversity = []for td in Td:singleUniversity.append(td.text.strip())allUniversity.append(singleUniversity)return allUniversity

得到处理好的数据之后,我们可以将数据保存到excel表中,这时候就需要用到 xlwt库中的方法,将数据按 'top', '大学名称', '省市', '类型', '总分', '办学层次'的顺序打印到excel表中,将此代码封装成函数如下:

# 保存处理好的数据到 excel 中
def saveData(datalist, savePath):book = xlwt.Workbook(encoding='utf-8', style_compression=0)sheet = book.add_sheet('中国大学排名', cell_overwrite_ok=True)col = ['top', '大学名称', '省市', '类型', '总分', '办学层次']for i in range(len(col)):sheet.write(0, i, col[i])for i in range(len(col)):for j in range(len(datalist)):sheet.write(j+1, i, datalist[j][i])book.save(savePath)

最终在main()方法中调用这些方法,运行即可:

def main():url = 'https://www.shanghairanking.cn/rankings/bcur/2021'html = askUrl(url)data = getData(html)saveData(data, '中国大学排名.xls')

运行结果

声明

本文章部分内容来源于老师授课ppt

Python练习-爬虫(附加爬取中国大学排名)相关推荐

  1. python中国大学排名爬虫写明详细步骤-Python爬虫——定向爬取“中国大学排名网”...

    内容整理自中国大学MOOC--北京理工大学-蒿天-Python网络爬虫与信息提取 相关实战章节 我们预爬取的url如下 网页节选 在浏览器中读取网页源代码 可以 发现表格数据信息是直接写入HTML页面 ...

  2. python爬虫分析大学排名_Python爬虫之爬取中国大学排名(BeautifulSoup库)

    image.png 我们需要打开网页源代码,查看此网页的信息是写在html代码中,还是由js文件动态生成的,如果是后者,那么我们目前仅仅采用requests和BeautifulSoup还很难爬取到排名 ...

  3. Python爬虫系列(二):爬取中国大学排名丁香园-用户名和回复内容淘宝品比价

    Python爬虫系列(二):爬取中国大学排名&丁香园-用户名和回复内容&淘宝品比价 目录 Python爬虫系列(二):爬取中国大学排名&丁香园-用户名和回复内容&淘宝品 ...

  4. Python爬取中国大学排名,并且保存到excel中

    前言 以下文章来源于数据分析和Python ,作者冈坂日川 今天发的是python爬虫爬取中国大学排名,并且保存到excel中,当然这个代码很简单,我用了半小时就写完了,我的整体框架非常清晰,可以直接 ...

  5. python中国最好大学排名_国内大学排名如何?用Python爬取中国大学排名

    国内大学排名如何?用Python爬取中国大学排名准备阶段需要的库robots协议上代码代码框架*获取url信息*解析信息*输出数据*主函数结果 准备阶段 新手入门,不喜勿喷,这篇文章的内容其实也是在中 ...

  6. 爬虫爬取中国大学排名top100并简单可视化分析

    爬虫爬取中国大学排名top100并简单可视化分析. 目标链接 http://www.zuihaodaxue.cn/zuihaodaxuepaiming2019.html 实践环境 pycharm201 ...

  7. 第一个爬虫程序之定向爬取中国大学排名(收获良多,不仅仅是写个程序,更是编程的步骤方法)

    第一个爬虫程序之定向爬取中国大学排名(收获良多,不仅仅是写个程序,更是编程的想法) 名称:定向爬取--中国大学排名定向爬取 首先,爬之前,看看你要定向爬取的网站和数据是什么类型的? 打开你要爬取网站, ...

  8. 爬取中国大学排名并以csv格式存储

    爬取中国大学排名并以csv格式存储 import requests from bs4 import BeautifulSoup import bs4def get_content(url):try:u ...

  9. 【史上最骚爬虫|疯狂爬取中国大学mooc】太燃了,爬虫vs慕课反爬世纪大战|No.1

    爬取中国大学全网mooc:NO.1 作者:夜斗小神社 IDEA工具:PyCharm 抓包工具:Fiddler 时间:2021/5/2 小夜斗与爬虫已经很久没交流过辽,想着能重新把爬虫捡起来,这次就试一 ...

最新文章

  1. 怎么将文件转换成linux文件,Linux将DOS文件格式转换成UNIX文件格式的方法
  2. arduino 温度调节器_多点测平均温度实现智能控制(arduino-ds18b20)
  3. java 正则表达式提取价格
  4. Material delta download的deletion处理原理
  5. 速看 | 电子元器件如何确定好坏?
  6. aws ecr_在ECR上推送Spring Boot Docker映像
  7. CORS漏洞的利用方式(精)
  8. PHP编码规范 代码样式风格规范
  9. Java服务器多站点,java客户端web服务器连接到多个web服务器
  10. html 悬浮qq,js悬浮QQ在线客服代码(支持拖动)
  11. 三星董事长去世享年78岁,临终前最为遗憾的一件事
  12. ubuntu QT Creator Fatal IO error 2 (没有那个文件或目录) on X server :0
  13. 类似ftp文件服务器有哪些,FTP的替代品有哪些,你知道吗?
  14. 如何将阿里图标库的引入项目中?
  15. 【微信H5】分享出去是链接,不是卡片的原因及解决方案
  16. Sketch中英文切换教程
  17. if条件语句基本语法
  18. 水位传感器c语言程序,简单水位报警器(水浸传感器)单片机源码
  19. 渠道广告联盟SDK接入思路总结
  20. 洛谷P2331最大子矩阵

热门文章

  1. 认知科学与广义进化论
  2. 逃离贼船?新方舟需要我们去创造。
  3. 面试相关的linux装机必备知识点
  4. 2021-08-10第一章绪论1.1统计学与医学统计学
  5. 符合FDA标准的邮件安全证书(S/MIME)有哪些?
  6. erlang send剖析及参数意义
  7. 美团-深度学习在点评推荐平台排序中的运用
  8. 【调剂】齐鲁工业大学(山东省科学院)2020年硕士研究生预调剂通知
  9. 溪云初起日沉阁 山雨欲来风满楼
  10. 快速剪辑-助力度咔智能剪辑提效实践