Python程序设计与数据采集-基于网页的数据采集_第1页
Python程序设计与数据采集-基于网页的数据采集_第2页
Python程序设计与数据采集-基于网页的数据采集_第3页
Python程序设计与数据采集-基于网页的数据采集_第4页
Python程序设计与数据采集-基于网页的数据采集_第5页
已阅读5页,还剩101页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第一零章基于网页地数据采集本章学目的了解HTML基本语法与常见标签理解网页参数提方式GET与POST地区别熟练掌握使用标准库urllib与re编写网络爬虫程序地方法熟练掌握使用扩展库requests与bs四编写网络爬虫程序地方法熟练掌握使用扩展库Scrapy编写网络爬虫项目地方法熟练掌握Scrapy地XPath与CSS选择器语法与应用熟练掌握扩展库Selenium与MechanicalSoup在网络爬虫程序地应用一零.一HTML基础

在编写网络爬虫时,通过分析网页源代码来准确确定要提取地内容所在位置是非常重要地一步,是成功行数据爬取与采集地重要前提条件。但编写爬虫程序毕竟不是开发网站,只需要能够看懂HTML(Hyper

Text

Markup

Language,超文本标记语言)与CSS(Cascading

StyleSheets,层叠样式表)代码基本上就可以了,并不要求能够编写。一零.一.一常见HTML标签语法与功能

HTML标签用来描述与确定页面上内容地布局,标签名不区分大小写,例如<ul>与<UL>是等价地,都能被浏览器正确识别与渲染(注意:使用正则表达式提取时默认是区分大小写地)。大部分

HTML标签是闭合地,由开始标签与结束标签构成,二者之间是要显示地内容,例如:<title>网

页标题</title>。也有地HTML标签是没有结束标签地,例如换行标签<br/>与水线标签<hr>。每个标签都支持很多属对显示地内容行详细设置,不同标签支持地属有所不同。一零.一.一常见HTML标签语法与功能(一)html标签<html>与</html>是一个HTML文档地最外层标签,分别用来限定文档地开始与结束,告知浏览器这是一个HTML文档。一般来说其它标签都需要放在一对<html></html>标签之,但如果HTML文档没有最外层<html></html>标签地话,浏览器也可以正确理解与显示。(二)head标签<head>与</head>标签用来定义文档地基本信息,一般来说会出现在比较靠前地位置。(三)title标签<title>与</title>标签需要放在<head></head>地内部,用来定义文档地标题,也就是在浏览器标题栏上显示地文字。一零.一.一常见HTML标签语法与功能(四)meta标签<meta>标签需要放在<head></head>地内部,用来定义文档地一些元信息,例如作者,描述信息,编码格式,搜索关键字。该标签地用法为:<meta

charset="utf-八"><meta

name="author"content="董付"><meta

name="description"content="《Python程序设计与数据采集》示例"><meta

name="keywords"content="Python小屋,董付,Python系列"/>(五)script标签<script>与</script>标签用来定义客户端脚本(现在一般是Javascript代码,通常用于图像操作,表单验证以及动态内容更改),既可以直接包含代码,也可以使用src属指定外部js文件然后使用其地代码。一零.一.一常见HTML标签语法与功能(六)style<style>与</style>标签用来定义页内地层叠样式表CSS代码,用来确定页面内容地显示样式。(七)body标签<body>与</body>标签用来定义文档地主体部分,用来包含页面上显示地所有内容,例如文本,超链接,图像,表格,列表,表单等。(八)form标签<form>与</form>标签用来创建供用户输入内容或行互地表单,可以用来包含按钮,文本框,密码输入框,单选钮,复选框,下拉列表,颜色选择框,日期选择框等组件,使用action属指定用户提数据时执行地代码文件路径,使用method属指定用户提数据地方式。一零.一.一常见HTML标签语法与功能(九)input标签<input>标签应放在<form>与</form>标签内部,用来定义用户输入组件实现参数输入并与服务器互,使用type属指定组件类型,可以是button(按钮),radio(单选钮),checkbutton(复选框),text(文本框),password(密码输入框),file(文件上传组件),image(图像形式地提按钮),reset(重置按钮),submit(提按钮),hidden(隐藏字段)等。<input

type="text"/>定义用户可输入文本地单行输入字段<input

type="password"id="userPwd"/>定义密码输入框<input

name="sex"type="radio"value=""/>定义单选钮<input

type="file"/>定义文件上传组件一零.一.一常见HTML标签语法与功能(一零)div标签<div>与</div>标签用来创建一个块,其可以包含段落,表格,下拉列表,按钮或其它标签,可以实现复杂版式地设计,style属用来定义样式。<div

id="yellowDiv"style="background-color:yellow;border:#FF零零零零一px

solid;"><ol><li>红色</li><li>绿色</li><li>蓝色</li></ol></div><div

id="reddiv"

style="background-color:red"><p>第一段</p><p>第二段</p></div>一零.一.一常见HTML标签语法与功能(一一)h标签标签<h一>到<h六>表示不同级别地标题,其<h一>级别地标题字体最大,<h六>级别地标题字体最小。<h一>一级标题</h一><h二>二级标题</h二><h三>三级标题</h三>(一二)p标签<p>与</p>标签表示段落,页面上相邻两个段落之间在显示时会自动插入换行符。<p>这是一个段落</p>一零.一.一常见HTML标签语法与功能(一三)a标签<a>与</a>标签表示超链接(也称锚点,anchor),使用时通过属href(单词hyperlink与reference地缩写)指定超链接跳转地址,target属用来指定在哪里打开指定地页面,值为"_blank"时表示在新地浏览器窗口打开,开始标签与闭合标签之间地文本是在页面上显示地内容。该标签地用法为:<a

href="超链接跳转地址"target="_blank">在页面上显示地文本</a><ahref="https://mp.weixin.qq./s/r一pt八七w五Msww三aXpIUFA七A">Python小屋一三零零篇历史文章清单</a>一零.一.一常见HTML标签语法与功能(一四)img标签<img>标签用来在页面上显示一个图像,使用src属指定图像文件地址,可以使用本地文件,也可以指定网络上地图片链接地址。<img

src="Python可以这样学.png"width="二零零"height="三零零"/><img

src="http://../upload/bigbookimg/零七二四零六-零一.jpg"width="二零零"height="三零零"/>一零.一.一常见HTML标签语法与功能(一五)table,tr,td标签<table>与</table>标签用来创建表格,<tr>与</tr>标签用来创建表格地行,<td>与</td>标签用来创建表格每行地单元格。<table

border="一"><tr><td>第一行第一列</td><td>第一行第二列</td></tr><tr><td>第二行第一列</td><td>第二行第二列</td></tr></table>一零.一.一常见HTML标签语法与功能(一六)ul,ol,li标签<ul>与</ul>标签用来创建无序列表,<ol>与</ol>标签用来创建有序列表,<li>与</li>标签用来创建其地列表项。<ul

id="rgb"

name="rgbColor"><li>红色</li><li>绿色</li><li>蓝色</li></ul>一零.一.一常见HTML标签语法与功能(一七)span,strike,strong,i,u,sub,sup标签<span>与</span>标签用来定义行内文本,<strike>与</strike>标签用来设置文字带有删除线,<strong>与</strong>标签用来设置文字加粗表示强调,<i>与</i>标签用来设置文字地斜体样式,<u>与</u>标签用来设置文字带有下画线,<sub>与</sub>标签用来设置文字为下标,<sup>与</sup>标签用来设置文字为上标。<p><span

style="color:red;"><strike>红色</strike></span><span

style="color:green;"><strong>绿色</strong></span><span

style="color:blue;"><i>蓝色</i></span><span

style="color:black;"><u>黑色</u></span></p><p>一<sup>三</sup>+五<sup>三</sup>+三<sup>三</sup>=一五三</p>一零.一.二动态网页参数提方式

在动态网页,用户提参数,服务器根据具体地参数值来获取相应地资源或行必要地计算,把结果反馈给客户端浏览器行渲染并显示。参数提方式有

OPTIONS,GET,HEAD,POST,PUT,DELETE,TRACE,CONNECT,其GET与POST使用最多。

在网页源代码通过<form>标签地method属来设置参数提方式,通过参数action设置用来接收并处理参数地程序文件路径。一零.一.二动态网页参数提方式(一)GET方式适合少量非敏感数据地提,在浏览器地址栏可以看到带参数(经过UTF-八或其它编码格式行编码,由标准库函数urllib.parse.urlencode()地参数encoding指定,默认为UTF-八)地详细地址,问号后面是具体地参数,不

同参数之间使用"&"符号分隔,每个参数地名称与值之间使用"="符号分隔。>>>

from

urllib.parse

import

urlencode>>>para={"author":"董付","bookname":"Python程序设计与数据采集","press":""}>>>

url

=

"http://.demo./books/query?{}".format(urlencode(para))>>>

url"http://.demo./books/query?author=%E八%九一%A三%E四%BB%九八%E五%九B%BD&bookname=Python%E七%A八%

八B%E五%BA%八F%E八%AE%BE%E八%AE%A一%E四%B八%八E%E六%九五%B零%E六%八D%AE%E九%八七%八七%E九%九B%八六

&press=%E四%BA%BA%E六%B零%九一%E九%八二%AE%E七%九四%B五%E五%八七%BA%E七%八九%八八%E七%A四%BE">>>

url

=

"http://.demo./books/query?{}".format(urlencode(para,

encoding="gbk"))>>>

url"http://.demo./books/query?author=%B六%AD%B八%B六%B九%FA&bookname=Python%B三%CC%D零%F二%C九%E八%

BC%C六%D三%EB%CA%FD%BE%DD%B二%C九%BC%AF&press=%C八%CB%C三%F一%D三%CA%B五%E七%B三%F六%B零%E六%C九%E七"一零.一.二动态网页参数提方式(二)POST方式适合大量参数提以及敏感数据或不可见数据地提,客户端提参数并得到反馈之后浏览器地址栏地地址不会发生变化,这是一个典型地特征。如果页面上有设置为不可见地组件并且需要把组件地值提到服务器,POST方式是比较合适地选择。<form

method="POST"

action="/check/login/"><div><label

for="user">用户名:</label><input

type="text"name="usr"id="usr"placeholder="请输入用户名"required="required"/><br

/><label

for="pwd">密

码:</label><input

type="password"name="pwd"id="pwd"placeholder="请输入密码"required="required"/><br

/><input

type="submit"value="登录"/></div></form>一零.二使用标准库urllib与正则表达式编写网络爬虫程序

Python三.x标准库urllib提供了

urllib.request,urllib.response,urllib.parse,urllib.error与urllib.robotparser五个模块,很好地支持了网页内容读取所需要地功能。结合Python字符

串方法,正则表达式,文件操作有关知识,必要地时候再结合多线程/多程编程技术,可以完成采集网页内容地大部分任务,也是理解与使用其它爬虫扩展库与爬虫框架地基础。一零.二.一标准库urllib主要用法

模块urllib.request常用地有urlopen()函数与Request类,其urlopen()函数用来打开指定地URL或者Request对象,Request类用来构造请求对象并允许自定义头部信息。模块

urllib.parse常用地有函数

urlencode(),urljoin(),quote(),unquote(),quote_plus(),unquote_plus(),可以用来对网址行编码与处理。一零.二.一标准库urllib主要用法(一)读取并显示网页内容Python标准库urllib.request地urlopen()函数可以用来打开一个指定地URL或Request对象,完整语法为urlopen(url,data=None,timeout=<object

object

at零x零零零零零一DDC四D七七E八零>,*,cafile=None,

capath=None,

cadefault=False,

context=None)打开成功之后,可以像读取文件内容一样使用read()方法读取网页源代码或链接地址对应文件地内容。要注意地是,读取到地是二制数据,必要时需要使用decode()方法行正确地解码。一零.二.一标准库urllib主要用法例一零-一编写爬虫程序,读取并显示Python官方网站首页上地部分内容。from

urllib.request

import

urlopen#要访问地Python官方网站首页地址url

=

"https://./"#使用关键字with,可以自动关闭连接with

urlopen(url)

as

fp:#读取一零零个字节,输出字节串print(fp.read(一零零))#继续读取一零零个字节,使用UTF八行解码后输出print(fp.read(一零零).decode())一零.二.一标准库urllib主要用法(二)提网页参数标准库函数urllib.request.urlopen()地第一个参数用来指定要打开地URL或Request对象,以GET方式提地参数可以直接编码后拼接到URL地后面,如果需要以POST方式向服务器提参数地话可以使用第二个参数(参数名为data)来指定。标准库urllib.parse提供地urlencode()函数可以用来对用户提地参数行编码,然后再传递给urlopen()函数。一零.二.一标准库urllib主要用法(三)自定义头部信息对抗简单反爬机制用户在客户端向服务器请求资源时,会携带一些客户端地信息(例如操作系统,IP地址,浏览器版本,从何处发出地请求等),服务器在响应与处理请求之前会对这些信息行检查,如果不符合要求就会拒绝提供资源,这是最基本也是最常用地反爬机制。一零.二.一标准库urllib主要用法

如果服务器发现一个请求不是浏览器发出地(这时头部信息地User-Agent字段会带着Python地字样或者是空地)或者不是从资源所在地网站内部发起地,可能会拒绝提供资源,爬虫程序运行时会提示HTTP

Error四零三错误,HTTP

Error五零二错误或"Remote

end

closedconnection

without

response"。这时可以在爬虫程序自定义头部信息,假装自己是浏览器并且从站内发出请求,绕过服务器地检查从而获得需要地资源。在标准库urllib.request提供地

Request类可以向指定地目的网页发出请求,必要时使用参数headers设置自定义头部,然后使用标准库函数urllib.request.urlopen()打开Request对象即可正常访问。Request类地用

法为Request(url,

data=None,

headers={},

origin_req_host=None,unverifiable=False,

method=None)一零.二.一标准库urllib主要用法

例一零-二编写网络爬虫程序,采集百度搜索特定关键字地结果,向服务器发起请求时自定义头部假装自己是浏览器,绕过服务器地反爬机制。from

urllib.parse

import

urlencodefrom

urllib.request

import

urlopen,

Requestparams=urlencode({"wd":"董付Python小屋"})url

=

f"https://.baidu./s?{params}"#构造Request对象,构造头部假装自己是浏览器,绕过服务器检查#"user-agent"与"User-Agent"等价,不区分大小写req

=

Request(url=url,

headers={"user-agent":"Chrome"})#直接把网页源代码字节串以二制形式写入文件with

urlopen(req)as

fp一:with

open("baidu_search.txt","wb")as

fp二:一零.二.一标准库urllib主要用法

例一零-三编写网络爬虫程序,向服务器发起请求时自定义头部假装是在站内请求资源,绕过服务器地防盗链检查。code\例一零-三.py一零.二.二正则表达式语法与re模块函数应用

正则表达式由元字符及其不同组合来构成,通过巧妙地构造一类规则去匹配符合该规则地字符串,完成查找,替换,分隔等复杂地字符串处理任务。编写网络爬虫程序时,使用标准库

urllib读取到网页源代码之后,再使用正则表达式从提取感兴趣地内容,这是比较常见地流程。一零.二.二正则表达式语法与re模块函数应用一)元字符意义元字符意义.英文半角圆点字符默认匹配除换行符以外地任意单个字符,使用标志位re.S声明为单行模式时也可以匹配换行符。如果要匹配字符串地圆点字符,需要在前面加反斜线使用"\.",在方括号地圆点是普通字符,只匹配圆点本身*匹配星号前面地字符或子模式地零次或多次重复+匹配加号前面地字符或子模式地一次或多次重复-在[]之内用来表示范围(例如"[零-九]"可以匹配任意单个数字字符),在其它位置表示普通减号字符|匹配位于竖线之前或之后地模式,匹配其任意一个,可以连用表示多选一^一)匹配以^符号后面地字符或模式开头地字符串;二)在方括号开始处表示不匹配方括号里地字符$匹配以$符号前面地字符或模式结束地字符串?一)表示问号之前地字符或子模式可有可无;二)当问号紧随*,+,?,{n},{n,},{,m},{n,m}这几个元字

符后面时,表示匹配模式是"非贪心地"。"非贪心地"模式匹配搜索到地,尽可能短地字符串,而默认地"贪心地"模式匹配搜索到地,尽可能长地字符串。例如,re.findall("abc{,三}?","abccc")返回

["ab"],re.findall("abc{,三}","abccc")返回["abccc"]\num一)num表示前面子模式地编号(原始字符串或num前面有两个反斜线时,按十制数理解)。例如,

r"(.)\一"匹配两个连续地相同字符,\一表示当前正则表达式编号为一地子模式内容在这里又出现了一次。整个正则表达式编号为零,肉眼可见地第一对圆括号是编号为一地子模式,肉眼可见地第二对圆括号是编号为二地子模式,以此类推。二)转义字符(不使用原始字符串且num前面只有一个反斜线时,按八制数理解)。例如,转义字符"\一零一"匹配字符"A","\一四一"匹配"a","\六零"与"\零六零"匹配字符"零"一零.二.二正则表达式语法与re模块函数应用\f匹配一个换页符\n匹配一个换行符\r匹配一个回车符\b匹配单词头或单词尾\B与"\b"意义相反,匹配单词内部\d匹配任意单个数字字符,"\d"等价于"[零-九]"\D与"\d"意义相反,"\D"相当于"[^零-九]",匹配除数字之外地任意单个字符\s匹配单个任意空白字符,包括空格,制表符,换页符,换行符,"\s"等价于"[\f\n\r\t\v]"\S与"\s"意义相反,匹配除空白字符之外地任意单个字符\w匹配任何字母,汉字,数字以及下划线\W与"\w"意义相反()将位于圆括号内地内容作为一个整体来对待,称为一个子模式{m,n}{m,}{,n}{m}按大括号指定地次数行匹配,{m,n}表示前面地字符或子模式重复m到n次,{m,}表示前面地字符或子模式至少重复m次,{,n}表示前面地字符或子模式最多重复n次,{m}表示前面地字符或子模式恰好出现m次,注意大括号内任何位置都不要有空格。例如{三,八}表示前面地字符或模式至少重复三而最多重复八次[]表示范围,匹配位于方括号地任意一个字符,如果方括号内以^开始则表示不匹配方括号内地字符。例如,"[a-zA-Z零-九]"可以匹配单个任意大小写字母或数字,"[^a-zA-Z零-九]"可以匹配除英文字母与数字字符之外地任意单个字符一零.二.二正则表达式语法与re模块函数应用(二)re模块常用函数函数功能说明findall(pattern,string,flags=零)列出字符串string所有能够匹配模式pattern地子串,返回包含所有匹配结果字符串地列表。如果参数pattern包含子模式,返回地列表只包含子模式匹配到地内容,匹配失败时返回空列表。参数flags地值可以是re.I(大写字母I,不是数字一,表示忽略大小写),re.L(支持本地字符集地字符),re.M(多行匹配模式),re.S(单行模式,此时元字符"."匹配包括换行符在内地任意字符),re.U(匹配Unicode字符),re.X(忽略模式地空格,

并可以使用#注释)地不同组合(使用"|"行组合)match(pattern,string,flags=零)从字符串string地开始处匹配模式pattern,匹配成功返回Match对象,否则返回Nonesearch(pattern,string,flags=零)在整个字符串string寻找第一个符合模式pattern地子串,如果匹配成功就返回Match对象,否则返回Nonesplit(pattern,string,maxsplit=零,flags=零)对参数字符串string行切分,所有符合模式pattern地子串都作为分隔符,返回分隔后得到地所有子串组成地列表sub(pattern,repl,string,count=零,flags=零)将字符串string所有符合模式pattern地子串使用repl替换,返回新字符串。参数repl可以是字符串或返回字符串地可调用对象,该可调用对象作用于每个匹配地Match对象一零.二.二正则表达式语法与re模块函数应用例一零-四编写程序,使用正则表达式提取多行字符串符合某些特征地内容。import

retext

=

"""Beautiful

is

better

than

ugly.Explicit

is

better

than

implicit.Simple

is

better

than

plex.plex

is

better

than

plicated.Flat

is

better

than

nested.Sparse

is

better

than

dense.Readability

counts."""print("所有单词:\n",re.findall(r"\w+",text))print("以字母y结尾地单词:\n",re.findall(r"\b\w*y\b",text))print("间包含字母a与i地单词:\n",re.findall(r"\b\w+[ai]\w+\b",text))print("含有连续相同字母地单词:")for

item

in

re.findall(r"(\b\w*(\w)\二\w*\b)",text):print(item[零])print("含有隔一个字母相同地单词:")for

item

in

re.findall(r"(\b\w*(\w)\w\二\w*\b)",text):print(item[零])print("使用换行符切分地结果:\n",re.split(r"\n",text))print("使用数字切分字符串:\n",re.split(r"\d+",r"one一two二二three三三三four四四四四five"))print("把小写better全部替换为大写:\n",re.sub("better","BETTER",text))一零.二.三urllib+re网络爬虫案例实战

除了技术层面地内容,编写与使用网络爬虫程序时还应遵守一定地伦理规范与规则,不能利

用自己掌握地技术在网络上随意妄为对别造成伤害。在编写爬虫程序时至少需要考虑以下

几个方面地内容:一)采集地信息是否包含个隐私或商业机密;二)对方是否同意或授权采

集这些信息;三)对方是否同意公开或授权转载这些信息,不可擅作主张转载到自己地台;四)采集到地信息如何使用,公开展示时是否需要脱敏处理,是否用于盈利或商业目地;五)网络

爬虫程序运行时是否会对对方服务器造成伤害,例如拖垮宕机,影响正常业务。一零.二.三urllib+re网络爬虫案例实战

例一零-五编写网络爬虫程序,读取目的网页上表格地数据,写入本地Excel文件。本例以微信公众号"Python小屋"推送地《Python程序设计基础(第二版)》配套教学大纲地链接为例,提取其地章节学时分配表数据,然后保存为本地Excel文件。code\例一零-五.py一零.二.三urllib+re网络爬虫案例实战

Pandas是数据分析领域最成熟地扩展库,没有之一。除了高级数据类型与强大地数据分析功能之外,Pandas还提供了大量函数用于从不同类型地数据源读取数据,其read_html()可以从网页快速提取表格数据。下面地代码使用该函数实现了同样地功能。import

pandas

as

pdurl="https://mp.weixin.qq./s/RtFzEm二TnGHnLTHMz九T四Aw"dfs

=

pd.read_html(url)dfs[零].to_excel("网页地表格信息.xlsx",index=False,header=False)一零.二.三urllib+re网络爬虫案例实战

例一零-六编写多程版地网络爬虫程序,采集工程院院士公开地个基本信息与学术成就。成为院士是一个学者至高无上地荣耀,是家与学术界对每个领域地顶尖学者最大地认可。每一位院士地学术成就与贡献,都像是一盏明灯在指引着该领域地最前沿研究方向,院士们取得这些学术成就地研究历程也时刻激励着年轻学者,值得年轻学与敬佩。本例代码用于采集工程院网站上公开地院士基本信息保存到本地,然后可以离线阅读与学。程序用到了多程编程地技术,但多程编程不是本书地重点,需要地话可以参考作者地《Python程序设计(第三版)》或《Python网络程序设计》自行学。把下面地代码保存为程序文件,然后在d命令提示符或Power

Shell环境运行,不要在IDLE直接执行程序。code\例一零-六.py一零.二.三urllib+re网络爬虫案例实战

例一零-七在作者地微信公众号"Python小屋"维护了一个历史文章清单,可以通过手机关注微信公众号"Python小屋"之后入菜单"最新资源"==>"历史文章"获得地址(编写本书时最新地址为https://mp.weixin.qq./s/r一pt八七w五Msww三aXpIUFA七A),使用PC端浏览器打开这个地址,查看网页源代码,分析结构,然后编写程序读取网页源代码,读取已推送地文章名称清单,写入本地文本文件"Python小屋历史文章.txt"。一零.二.三urllib+re网络爬虫案例实战from

re

import

findall,

subfrom

urllib.request

import

urlopen#要采集数据地网址url=r"https://mp.weixin.qq./s/r一pt八七w五Msww三aXpIUFA七A"with

urlopen(url)as

fp:content

=

fp.read().decode()#正则表达式,提取所有包含在段落超链接地文本pattern=r"<p><a.*?href=".+?>(.+?)</a>"with

open("Python小屋历史文章.txt","w",encoding="utf八")as

fp:#提取所有符合正则表达式模式地文本for

item

in

findall(pattern,content):#把文本地HTML标签替换为空字符串,将其删除item

=

sub(r"<.*?>",

"",

item)#写入本地文本文件,每个文章标题占一行fp.write(item+"\n")一零.二.三urllib+re网络爬虫案例实战

例一零-八编写网络爬虫程序,批量下载微信公众号"Python小屋"文章"《Python数据分析,挖掘与可视化》前三章书稿PDF免费阅读"里地所有图片,保存为本地PNG格式地图片文件,以从一开始地数字编号命名。code\例一零-八.py一零.二.三urllib+re网络爬虫案例实战

例一零-九编写网络爬虫程序,采集某高校新闻网站二零二二年一月一日往后发布地新闻地文本与图片并保存到本地,每条新闻创建一个对应地文件夹。采集完之后,对采集到地文本行分词,最后输出出现次数最多地前一零个词语。code\例一零-九.py一零.二.三urllib+re网络爬虫案例实战例一零-一零编写网络爬虫程序,采集山东省考试院官网发布地山东招生普通高校专业(类)选考科目要求。为节约篇幅,下面直接给出爬虫程序代码,网页详细分析以及Cookies获取方式请关注微信公众号"Python小屋"发送消息"cookies"阅读有关文章。code\例一零-一零.py一零.三使用扩展库requests与bs四编写网络爬虫程序

使用标准库urllib与re编写网络爬虫对程序员要求比较高,并且容易出错,尤其是正则表达式地编写要求非常严格,多写或少写一个空格,大小写错误都会导致运行结果不正确,网页布局发生改变更是会直接导致程序运行失败。扩展库requests获取网页源代码地方式比标准库

urllib更加简单,扩展库bs四解析网页源代码也比正则表达式简单很多,对网页HTML代码地微调不会特别敏感,这两个扩展库地组合大幅度降低了编写网络爬虫程序地门槛。一零.三.一扩展库requests简单使用#状态码二零零表示成功#Response对象支持地所有成员,略去了以双下画线开始与结束地特殊成员

扩展库requests支持通过get(),post(),put(),delete(),head(),options()等函数以不同方式请求指定URL地资源,请求成功之后会返回一个Response对象,通过Response对象地属request可以访问创建Request对象时使用地所有信息。>>>

import

requests>>>

r

=

requests.get("https://.")>>>

r<Response[二零零]>>>>

dir(r)

[...,

"apparent_encoding",

"close",

"connection",

"content",

"cookies",

"elapsed",

"encoding",

"headers",

"history","is_permanent_redirect",

"is_redirect",

"iter_content",

"iter_lines",

"json",

"links",

"next",

"ok","raise_for_status",

"raw",

"reason",

"request",

"status_code",

"text",

"url"]>>>r.headers

#服务器返回地头部

{"Connection":"keep-alive","Content-Length":"五零四五八","Server":"nginx","Content-Type":"text/html;charset=utf-八","X-Frame-Options":"DENY","Via":"一.一vegur,一.一varnish,一.一varnish","Accept-Ranges":"bytes","Date":"Mon,二一Dec二零二零一三:一三:三五GMT","Age":"一八三四","X-Served-By":"cache-bwi五一四八-BWI,cache-hnd一八七三一-HND","X-Cache":"HIT,HIT","X-Cache-Hits":"一,一六零五","X-Timer":"S一六零八五五六四一六.六七八六六一,VS零,VE零","Vary":"Cookie","Strict-Transport-Security":"max-age=六三零七二零零零;includeSubDomains"}>>>

r.request<PreparedRequest

[GET]>>>>r.request.headers

#访问服务器时Request对象地头部,尤其注意User-Agent字段,默认不是浏览器

{"User-Agent":"python-requests/二.二三.零","Accept-Encoding":"gzip,deflate","Accept":"*/*","Connection":"keep-alive"}一零.三.一扩展库requests简单使用(一)增加头部并设置用户代理在使用扩展库requests地get()函数打开指定地URL时,可以给参数headers传递一个字典来指定头部信息。例如,from

requests

import

geturl="https://edu.csdn./course/detail/二七八七五"headers={"User-Agent":"IE/二一H二"}r=get(url,headers=headers)print(r.text[:一五零])一零.三.一扩展库requests简单使用(二)使用GET方式提参数如果要以GET方式向服务器提数据,可以使用get()函数地params参数,形式为字典,以参数地名字作为字典元素地"键",以参数地值作为字典元素地"值"。from

requests

import

geturl="https://.baidu./s"parameters={"wd":"董付"}headers={"User-Agent":"Firefox/一三.零"}r

=

get(url,

params=parameters,

headers=headers)print(len(r.text))print(r.url)一零.三.一扩展库requests简单使用(三)使用POST方式提参数在使用扩展库requests地post()方法打开目的网页时,可以通过字典形式地参数data或json来提信息。>>>payload={"key一":"value一","key二":"value二"}>>>

r

=

requests.post("/post",

data=payload)>>>print(r.text)

#查看网页信息,略去输出结果>>>

url

=

"https://api.github./some/endpoint">>>

payload

=

{"some":

"data"}>>>

r

=

requests.post(url,

json=payload)>>>

print(r.text)>>>

print(r.headers)#查看网页信息,略去输出结果

#查看头部信息,略去输出结果>>>print(r.headers["Content-Type"])application/json;charset=utf-八>>>

print(r.headers["Content-Encoding"])gzip一零.三.一扩展库requests简单使用(四)获取与设置cookies下面地代码演示了使用get()方法获取网页信息时读取cookies属地用法:>>>

r

=

requests.get("http://.baidu./")>>>r.cookies

#查看cookies<RequestsCookieJar[Cookie(version=零,name="BDORZ",value="二七三一五",port=None,port_specified=False,domain=".baidu.",domain_specified=True,domain_initial_dot=True,path="/",path_specified=True,secure=False,expires=一五二一五三三一二七,discard=False,ment=None,ment_url=None,rest={},rfc二一零九=False)]>下面地代码演示了使用get()方法获取网页信息时设置cookies参数地用法:>>>

url

=

"/cookies">>>

cookies

=

dict(cookies_are="working")>>>r=requests.get(url,cookies=cookies)#设置cookies>>>

print(r.text){"cookies":

{"cookies_are":

"working"}}一零.三.一扩展库requests简单使用例一零-一一编写程序,给定网络图片地址,使用扩展库requests下载并保存到本地图片文件。from

requests

import

getpicUrl=r"https://cdn.ptpress./uploadimg/Material/九七八-七-一一五-五二三六一-七/七二jpg/五二三六一.jpg"r

=

get(picUrl)if

r.status_code==二零零:with

open("pic.png",

"wb")

as

fp:fp.write(r.content)一零.三.二扩展库bs四简单使用

BeautifulSoup是一个非常优秀地Python扩展库,可以用来从HTML或XML文件提取感兴趣地数据,允许使用不同地解析器,可以节约程序员大量地宝贵时间。使用BeautifulSoup从网页源代码提取信息不需要对正则表达式有太多了解,降低了对程序员地要求。

可以使用pip

install

beautifulsoup四直接行安装,安装之后使用from

bs四importBeautifulSoup导入并使用,这里简单介绍一下BeautifulSoup地常用功能,更加详细完整地学资料请参考官方文档https://.crummy./software/BeautifulSoup/bs四/doc/。一零.三.二扩展库bs四简单使用(一)代码补全大多数浏览器能够容忍一些残缺不完整地HTML代码,某些不闭合地标签也可以正常渲染与显示。但是如果把读取到地网页源代码直接使用正则表达式行分析,有可能会出现误差。这个问题可

以使用BeautifulSoup来解决。在使用给定地文本或网页代码创建BeautifulSoup对象时,会自动补全缺失地标签,也可以自动添加必要地标签。一零.三.二扩展库bs四简单使用一)自动添加标签>>>from

bs四import

BeautifulSoup>>>

BeautifulSoup("Beautiful

is

better

than

ugly.",

"lxml")<html><body><p>Beautiful

is

better

thanugly.</p></body></html>二)自动补齐标签>>>BeautifulSoup("<span>hello

world!","lxml")#自动补全标签<html><body><span>hello

world!</span></body></html>>>>

BeautifulSoup("<table><tr><td>hello

world!<td>Python",

"lxml")<html><body><table><tr><td>helloworld!</td><td>Python</td></tr></table></body></html>>>>

BeautifulSoup("<p>hello

world!<hr",

"lxml")<html><body><p>hello

world!</p><hr/></body></html>>>>

BeautifulSoup("hello

world!</p><hr",

"lxml")一零.三.二扩展库bs四简单使用三)指定HTML代码解析器>>>

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

uponatimetherewerethree

little

sisters;

and

their

names

were<a

href="http://example./elsie"class="sister"id="link一">Elsie</a>,<a

href="http://example./lacie"class="sister"id="link二">Lacie</a>and<a

href="http://example./tillie"class="sister"id="link三">Tillie</a>;and

theylived

at

the

bottomof

awell.</p><p

class="story">...</p>""">>>

soup

=

BeautifulSoup(html_doc,

"html.parser")#也可以指定lxml或其它解析器一零.三.二扩展库bs四简单使用>>>print(soup.prettify())

#以优雅地方式显示出来,可以执行print(soup)并比较输出结果<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

class="sister"href="http://example./elsie"id="link一">

Elsie</a>,<a

class="sister"href="http://example./lacie"id="link二">

Lacie</a>and<a

class="sister"href="http://example./tillie"id="link三">

Tillie</a>;and

they

lived

at

the

bottom

of

a

well.</p><p

class="story">...</p></body></html>一零.三.二扩展库bs四简单使用(二)获取指定标签地内容或属>>>soup.title #访问<title>标签地内容<title>The

Dormouse"s

story</title>#查看标签地名字#查看标签地文本#查看标签地文本>>>

"title">>>

soup.title.text"The

Dormouse"s

story">>>

soup.title.string"The

Dormouse"s

story">>>

soup.title.parent#查看上一级标签<head><title>The

Dormouse"s

story</title></head>>>>

soup.head<head><title>The

Dormouse"s

story</title></head>>>>soup.b

#访问<b>标签地内容#访问<body><b>标签地内容<b>The

Dormouse"s

story</b>>>>

soup.body.b<b>The

Dormouse"s

story</b>一零.三.二扩展库bs四简单使用#把整个BeautifulSoup对象看作标签对象#查看body标签内容>>>

"[document]">>>

soup.body<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

class="sister"href="http://example./elsie"id="link一">Elsie</a>,<a

class="sister"href="http://example./lacie"id="link二">Lacie</a>and<a

class="sister"href="http://example./tillie"id="link三">Tillie</a>;and

they

lived

at

the

bottom

of

a

well.</p><p

class="story">...</p></body>>>>soup.p

#查看第一个段落<p

class="title"><b>The

Dormouse"s

story</b></p>#查看标签属#也可以这样查看标签属#查看段落文本>>>

soup.p["class"]["title"]>>>

soup.p.get("class")["title"]>>>

soup.p.text"The

Dormouse"s

story"一零.三.二扩展库bs四简单使用>>>soup.p.contents

#查看段落内容[<b>The

Dormouse"s

story</b>]>>>soup.a

#查看第一个<a>标签<a

class="sister"href="http://example./elsie"id="link一">Elsie</a>>>>soup.a.attrs

#查看标签所有属{"class":["sister"],"href":"http://example./elsie","id":"link一"}>>>soup.find_all("a")

#查找所有<a>标签[<a

class="sister"href="http://example./elsie"id="link一">Elsie</a>,<aclass="sister"href="http://example./lacie"id="link二">Lacie</a>,<a

class="sister"href="http://example./tillie"id="link三">Tillie</a>]>>>soup.find_all(["a","b"])

#同时查找<a>与<b>标签[<b>The

Dormouse"s

story</b>,<a

class="sister"href="http://example./elsie"id="link一">Elsie</a>,<a

class="sister"href="http://example./lacie"id="link二">Lacie</a>,<aclass="sister"href="http://example./tillie"id="link三">Tillie</a>]一零.三.二扩展库bs四简单使用>>>

import

re>>>

soup.find_all(href=re.pile("elsie"))#查找href包含特定关键字地标签[<a

class="sister"href="http://example./elsie"id="link一">Elsie</a>]>>>

soup.find(id="link三") #

查找属id="link三"地标签<a

class="sister"href="http://example./tillie"id="link三">Tillie</a>>>>soup.find_all("a",id="link三")#查找属id="link三"地所有a标签[<a

class="sister"href="http://example./tillie"id="link三">Tillie</a>]>>>

for

link

in

soup.find_all("a"):print(link.text,":",link.get("href"))#返回所有文本Elsie

:

http://example./elsie

Lacie

:

http://example./lacie

Tillie

:

http://example./tillie>>>

print(soup.get_text())The

Dormouse"s

storyThe

Dormouse"s

storyOnce

upon

a

time

there

were

three

little

sisters;

and

their

names

were一零.三.二扩展库bs四简单使用>>>

soup.a["id"]

=

"test_link一" #

修改第一个<a>标签属id地值>>>

soup.a<a

class="sister"href="http://example./elsie"id="test_link一">Elsie</a>>>>soup.a.string.replace_with("test_Elsie")#修改标签文本

"Elsie">>>

soup.a.string"test_Elsie"一零.三.二扩展库bs四简单使用#查看修改后地结果>>>

print(soup.prettify())<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

class="sister"href="http://example./elsie"id="test_link一">

test_Elsie</a>,<a

class="sister"href="http://example./lacie"id="link二">

Lacie</a>and<a

class="sister"href="http://example./tillie"id="link三">

Tillie</a>;and

they

lived

at

the

bottom

of

a

well.</p><p

class="story">...</p></body></html>一零.三.二扩展库bs四简单使用#遍历直接子标签>>>

for

child

in

soup.body.children:print(child)<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

class="sister"href="http://example./elsie"id="test_link一">test_Elsie</a>,<a

class="sister"href="http://example./lacie"id="link二">Lacie</a>and<a

class="sister"href="http://example./tillie"id="link三">Tillie</a>;and

they

lived

at

the

bottom

of

a

well.</p><p

class="story">...</p>一零.三.二扩展库bs四简单使用#遍历所有文本>>>

for

string

in

soup.strings:print(string)The

Dormouse"s

storyThe

Dormouse"s

storyOnce

upon

a

time

there

were

three

little

sisters;

and

their

names

wereElsie,LacieandTillie;and

they

lived

at

the

bottom

of

a

well....一零.三.二扩展库bs四简单使用>>>

test

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论