——王宇阳—根据mooc课程总结记录笔记(Code_boy)

Requests库:自动爬去HTML页面、自动网络请求提交

robots.txt:网络爬虫排除标准

Beautiful Soup库:解析HTML页面(pycharm中安装bs4即可)

re正则表达式:对HTML数据分析选择

requests.get(url[,params = None,**kwargs])

url:获取网页的url链接

params:url中的额外参数,字典或字节流格式,可选

**kwargs:12个控制访问的参数

Response对象的属性{0.0.py}

属性

说明

r.status_code

HTTP请求的返回状态,200表示连接成功,404表示失败

r.text

HTTP响应内容的字符串形式,(即:url对应的页面内容)

r.encoding

从HTTP header中猜测的响应内容编码方式

r.apparent_encoding

从内容中分析出的响应内容编码方式(备选编码方式)

r.content

HTTP响应内容的二进制形式

实例:

 r = requests.get("http://www.baidu.com")
print(r.status_code) #返回状态码(内容值为‘200’表示访问成功)
#结果: 200
print(r.text) #返回响应内容的字符串形式
#结果:【即-baidu主页的源代码内容(存在乱码字符)】
print(r.encoding) #从HTTP header中猜测的响应内容编码方式
#结果: ISO-8859-1 即baidu页面的编码标准(方式 )
print(r.apparent_encoding) #从内容中分析出的响应内容编码方式[备选编码方式]
#结果: utf-8
print(r.content) #内容的二进制形式
#结果: 总之看不懂 r.encoding = 'utf-8' #(utf-8为r.apparent_encoding得到的结果)
print(r.text)
#结果就为人可看懂的响应内容 主要是通过r.encoding的重新定义类型,而r.text是参照encoding的编码方式

通用爬虫代码框架:

 def getHTMLText(url):
try:
r = requests.get(url,timeout = 30)
r.raise_for_status() #如果状态不是200 则抛出异常:requests.HTTPError(r.status_code)
r.encoding = r.apparent_encoding
return r.text
except:
return "产生异常" if __name__ == "__main__":
url = 'http://www.baidu.com'
print(getHTMLText(url))

Requests库的异常

异常

说明

requests.ConnectionError

网络连接错误异常,(如DNS查询失败,拒绝连接等)

requests.HTTPError

HTTP错误异常

requests.URLequired

URL缺失异常

requests.TooManyRedirects

超过最大重定向次数,产生重定向异常

requests.ConnectTimeout

连接远程服务器超时异常

requests.Timeeout

请求URL超时,产生超时异常

r.raise_for_status

如果不是200,产生异常: requetst.HTTPError

通用代码框架实例:

 def getHTMLText(url):
try:
r = requests.get(url,timeout = 30)
r.raise_for_status() #如果状态不是200 则抛出异常:requests.HTTPError(r.status_code)
r.encoding = r.apparent_encoding
return r.text
except:
return "产生异常" if __name__ == "__main__":
url = 'http://www.baidu.com'
print(getHTMLText(url))

Requests库的7个主要方法

方法

说明

requests.request()

构造一个请求,支撑以下的各方法的基础方法

requests.get()

获取HTML网页的只要方法,对应于HTTP的GET

requests.head()

获取HTML网页头信息的方法,对应于HTTP的HEAD

requests.post()

向HTML网页提交POST请求的方法,对应于HTTP的POST

requests.put()

向HTML网页提交PUT请求的方法,对应于HTTP的PUT

requests.patch()

向HTML网页提交局部修改请求,对应于HTTP的PATCH

requests.delete()

向HTML网页提交删除请求,对应于HTTP的DELETE

HTTP协议:

HTTP,Hypertext Transfer Protocol,超文本传输协议

HTTP是一个基于“请求与响应”模式的、无状态的应用层协议。

HTTP采用URL定位网络资源的标识

URL格式: http://host[:port][path]

host:合法的Internet主机域名或IP地址

port:端口号(缺省端口为80)

path:请求资源的路径

HTTP协议对资源的操作:

方法

说明

GET

请求获取URL位置的资源

HEAD

请求获取URL位置资源的响应信息报告,即获得该资源的头部信息

POST

请求向URL位置的资源后附加新的数据

PUT

请求向URL位置存储一个资源,覆盖原URL位置的资源

PATCH

请求局部更新URL位置的资源,即改变该出资源的部分内容

DELETE

请求删除URL位置存储的资源

理解PATCH和PUT的区别

假设URL位置有一组数据UserInfo,包括UserID、UserName等20个字段

需求:用户修改了UserName,其他不变

*采用PATCH,仅向URL提交UserName的局部更新请求【追加】

*采用PUT,必须将所有20个字段一并提交到URL,未提交字段被删除【覆盖追加】

 #requests库的head()方法 (请求获取URL位置资源的响应信息报告,即获得该资源的头部信息)
r = requests.head('http://httpbin.org/get')
print(r.headers)
'''
结果:
{'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.0',
'Date': 'Thu, 22 Nov 2018 03:52:22 GMT', 'Content-Type':
'application/json', 'Content-Length': '268',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials': 'true', 'Via': '1.1 vegur'}
'''
#requests库的post()方法(请求向URL位置的资源后附加新的数据)
payload = {'key1':'value1','key2':'value2'}
r = requests.post('http://httpbin.org/post',data = payload)
#向URL POST一个字典,自动编码未form(表单)
print(r.text)
'''
结果:
{
"args": {},
"data": "",
"files": {},
"form": {
"key1": "value1",
"key2": "value2"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Content-Length": "23",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.20.1"
},
"json": null,
"origin": "106.111.147.213",
"url": "http://httpbin.org/post"
}
'''
r = requests.post('http://httpbin.org/post',data = 'abc')
#向URL POST一个字符串自动编码为 data
print(r.text)
'''
结果:
{
"args": {},
"data": "abc",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Content-Length": "3",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.20.1"
},
"json": null,
"origin": "106.111.147.213",
"url": "http://httpbin.org/post"
}
'''
#requests库的put()方法 (请求向URL位置存储一个资源,覆盖原URL位置的资源)
payload = {'key1':'value1','key2':'value2'}
r = requests.put('http://httpbin.org/put',data = payload)
#向URL PUT一个字典,自动编码未form(表单)[和post的区别是会覆盖原有内容]
print(r.text)
'''
结果:
{
"args": {},
"data": "",
"files": {},
"form": {
"key1": "value1",
"key2": "value2"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Content-Length": "23",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.20.1"
},
"json": null,
"origin": "106.111.147.213",
"url": "http://httpbin.org/put"
}
'''

requests库的方法功能及使用:

requests.request(method,url,**kwargs)

method:请求方法,对应get/put/post等7种方法

r = requests.request(‘GET’,url,**kwargs)

r = requests.request(‘HEAD,’url,**kwargs)

r = requests.request(‘POST’,url,**kwargs)

r = requests.request(‘PUT’,url,**kwargs)

r = requests.request(‘PATCH’,url,**kwargs)

r = requests.request(‘delete’,url,**kwargs)

r = requests.request(‘OPTIONS’,url,**kwargs)#向服务获取相关的参数

url:拟获取页面的url链接

**kwargs:控制访问的参数,共13个(可选)

params:字典或字节序列,作为参数增加到url中链接部分系统会添加一个‘

data:字典、字节序列或文件对象,作为Request的内容

json:json格式的数据,作为Request的内容

headers:字典,HTTP定制头

cookies:字典或CookieJar,Request中的cookie *

auth:元组,支持HTTP认证功能 *

files:字典类型,传输文件

timeout:设定超时时间,单位:秒(时间内为返回,则返回异常)

proxies:字典类型,设定访问代理服务器,可以增加登陆认证

pxs={'http':'http://user:pass@10.10.10.1:1234'}
  r = requests.request('GET','http://www.baidu.com',proxies = pxs)

allow_redirects:True/False,默认为True,重定向开关

stream:True/False,默认为True,获取内容立即下载开关

verify:True/False,默认为True,认证SSL证书开关

cert:本地SSL证书路径

requests.get(url,params=None,**kwargs)*

url:页面的url链接

params:url中额外的参数,字典或字节流格式,可选

**kwargs:12个控制访问的参数

requests.head(url,**kwargs)

url:页面的url链接

**kwargs:13个控制访问的参数

requests.post(url,data=None,json=None,**kwargs)

url:页面的url链接

data:字典、字节序列或文件,Request的内容

json:JSON格式的数据,Request的内容

**kwargs:11个控制访问参数(data、json已使用)

requests.put(url,data=None,**kwargs)

url:页面的url链接

data:字典、字节序列或文件,Request的内容

**kwargs:12个控制访问的参数

requests.patch(url,data=None,**kwargs)

url:页面的url链接

data:字典、字节序列或文件,Request的内容

**kwargs:12个控制访问的参数

requests.delete(url,**kwargs)

url:删除页面的url链接

**kwargs:13个控制访问的参数


网络爬虫的尺寸:

样式

爬取网页,玩转网页

爬取网站,爬取系列网站

爬取全网

规模

小规模,数据量小的,爬取速度不敏感(>=90%)

中规模,数据规模较大,爬取速度敏感

大规模,搜索引擎,爬取速度关键

常用库

requests库

scrapy库

定制开发

网络爬虫的骚扰:

爬虫利用快速功能访问web服务器,服务器很难提供适应高速度爬虫的资源

受限于编写水平的目的,网络爬虫将会为web服务器带来巨大的资源开销

网络爬虫的法律风险:

服务器上的数据有产权归属

网络爬虫获取的数据后牟利将带来法律风险

网络爬虫==”爬亦有道”

限制爬虫条件:

>>>来源审查:判断 User-Agent 进行限制

·检查来访HTTP协议头的User-Agent域,只响应浏览器或友好爬虫的访问

>>>发布公告:Robots协议*

Robots Exclusion Standard 网络爬虫排除标准

作用:告知所有爬虫网站的爬取策略,要求爬虫遵守

形式:在网站根目录下的robots.txt文件

京东Robots协议:(https://www.jd.com/robots.txt)

User-agent: *

Disallow: /?*

Disallow: /pop/*.html

Disallow: /pinpai/*.html?*

User-agent: EtaoSpider

Disallow: /

User-agent: HuihuiSpider

Disallow: /

User-agent: GwdangSpider

Disallow: /

User-agent: WochachaSpider

Disallow: /

任何爬虫均应该遵守

不允许访问?开头的路径

不允许访问 /pop/*.html

不允许访问 /pinpai/*.html?*

EtaoSpider,

HuihuiSpider,

GwdangSpider,

WochachaSpider

被认定为恶意爬虫

被禁止爬取任何内容

Robots协议基本语法:

#

注释

*

代表所有

/

代表根目录

User-agent:*

指定爬虫(*表示所有爬虫)

Disallow:/

不允许爬虫访问的目录

爬虫基础1实例:(代码+总结){0.1.py}

 #实例:爬取京东商品
import requests
import os
'''
r = requests.get('https://item.jd.com/36826348085.html?jd_pop=14982c1c-64d9-4bab-ac5c-e40af7ce62a2&abt=0')
print(r.status_code)
print(r.encoding)
print(r.text[:1000])
#实例:爬取亚马逊 kv = {'User-Agent':'mozilla/5.0'} #打造访问头(伪造成一个浏览器)
r=requests.get('https://www.amazon.cn/dp/B073LJR2JF/ref=cngwdyfloorv2_recs_0/459-8865541-1481366?pf_rd_m=A1AJ19PSB66TGU&pf_rd_s=desktop-2&pf_rd_r=AT12APC0BDJ216Y55VSR&pf_rd_r=AT12APC0BDJ216Y55VSR&pf_rd_t=36701&pf_rd_p=d2aa3428-dc2b-4cfe-bca6-5e3a33f2342e&pf_rd_p=d2aa3428-dc2b-4cfe-bca6-5e3a33f2342e&pf_rd_i=desktop',headers=kv)
print(r.status_code)
print(r.text[:1000])
print(r.request.headers)
'''
#实例:百度搜索
#百度搜索的搜索url:http://www.baidu.com/s?wd:{搜索内容}
'''
keyword = 'python'
try:
kv = {'wd':keyword}
r = requests.get('http://www.baidu.com/s',params = kv)
print(r.request.url)
r.raise_for_status()
print(len(r.text))
except:
print("爬取失败")
'''
#案例:网络图片爬取和存储
'''
url = "http://img0.dili360.com/pic/2018/09/21/5ba4a6af2af103q29157813_t.jpg"
rot = "E://"
path = rot + url.split('/')[-1] #指定图片保存名为url地址中的后缀名(url)
try:
if not os.path.exists(rot): #查看有没有rot目录,没有则创建
os.mkdir(rot) #创建rot目录
if not os.path.exists(path): #查看path目录下有没有path文件
r = requests.get(url) #链接url地址
#with open(path,'wb') as f: #另一种文件打开和存储方式(???)
f = open(path,'wb') #打开文件
f.write(r.content) #r.content 响应url的二进制内容
f.close()
print("保存成功")
else:
print("文件已存在")
except:
print("爬取失败")
'''
#爬单个视频
'''
url = "http://video.pearvideo.com/mp4/adshort/20181121/cont-1480150-13269168_adpkg-ad_hd.mp4"
rot = "E://"
path = rot + url.split('/')[-1] #指定视频保存名为url地址中的后缀名(url)
try:
if not os.path.exists(rot): #查看有没有rot目录,没有则创建
os.mkdir(rot) #创建rot目录
if not os.path.exists(path): #查看path目录下有没有path文件
r = requests.get(url) #链接url地址
#with open(path,'wb') as f: #另一种文件打开和存储方式(???)
f = open(path,'wb') #打开文件
f.write(r.content) #r.content 响应url的二进制内容
f.close()
print("保存成功")
else:
print("文件已存在")
except:
print("爬取失败")
'''
#IP地址归属地的自动查询
#IP168查询链接url:http://ip138.com/ips138.asp?ip=123.125.6.1&action=2
#由上得出:IP查询url:http://ip138.com/ips138.asp?ip=ip地址 url = "http://ip138.com/ips138.asp"
ip = {"ip":"106.111.147.213"}
try:
r = requests.get(url,params=ip)
r.raise_for_status()
print(r)
#print(r.status_code)
r.encoding = r.apparent_encoding
print(r.text)
except:
print("爬取失败")

实例

小总结:

实例中可以看出,在搜索方便我们需要掌握url接口(会找、会用):中间利用到了params()函数来在url后添加新的内容,在调用该函数时最后url会在两者的结合处添加一个“?”符号

在网页爬取方面我们也看见了r.text[]的格式出现,这表示我们需要爬取网页源码的字符数;

实例中看见了图片和视频的爬取,并采用二进制的形式保存!

Beautiful Soup库:(pycharm中安装bs4){0.2 bs.py}

库的使用:

 form bs4 import BeautifulSoup

 soup = BeautifulSoup( ‘ <p>data</p> ‘ , ‘ html.parser ‘ )
 

Beautiful Soup库的理解:是解析、遍历、维护“标签树”的功能库

*Beautiful Soup库,也叫Beautiful Soup4或者bs4

目前常用的引用方法: for bs4 impor tBeautiful Soup

Beautiful Soup类 <<<等价>>> 标签树 <<<等价>>> HTML<\>

因为形成等价,所以通过Beautiful Soup类使得标签树形成了一个变量;

简单比喻:Beautiful Soup对应HTML/XML文档的全部内容

Beautiful Soup库解析器:

解析器

使用方法

条件

bs4的HTML解析器

Beautiful Soup ( mk , ‘html.parser‘ )

安装bs4库

lxml的HTML解析器

Beautiful Soup ( mk , ‘lxml’ )

pip install lxml

lxml的XML解析器

Beautiful Soup ( mk , ‘xml’ )

pip install lxml

html5lib的解析器

Beautiful Soup ( mk , ‘html5lib’ )

pip install html5lib

Beautiful Soup库的基本元素:

基本元素

说明

Tag

标签,最基本的信息组织单元,分别用<>和</>标明开头和结尾

Name

标签的名字,<p>...</p>的名字是‘p’,格式:<tag>.name

Attributes

标签的属性,字典形式组织,格式:<tag>.attrs

NavigableString

标签内非属性性字符串,<>...</>中字符串,格式:<tag>.string

Comment

标签内字符串的注释部分,一种特殊的Comment类型

Beautiful Soup库的函数:(表中的<tag>指标签)

函数

说明

备注

soup.<tag>

获取已被解析过的网页中的标签

t=soup.<tag>

[soup.<tag>].name

获取<tag>标签的名称

[soup.<tag>].parent.name

获取<tag>标签的上一层标签的名称

以此可向上类推

[soup.<tag>].attrs

获取<tag>标签的属性

[soup.<tag>].string

获取<tag>标签的非属性字符串/注释

代码实例(+说明)

 r = requests.get('http://python123.io/ws/demo.html')
print(r.text)
demo = r.text #demo == url网页代码
soup = BeautifulSoup(demo,'html.parser')
print(soup.prettify())
r = requests.get('http://python123.io/ws/demo.html')
demo = r.text
soup = BeautifulSoup(demo,"html.parser")
print(soup.title) #查找 title 标签
print(soup.a.string) #打印a标签的字符串内容
print(soup.a.name) #打印a标签的名字
print(soup.a.parent.name) #打印a标签的父标签(上一层标签)
print(soup.a.parent.parent.name) #打印a标签的父标签的上一层标签
tag = soup.a #soup:查找标签a
print(soup.a.attrs) #打印标签的属性
print(tag.attrs['class']) #打印标签属性中的‘class’的内容
print(tag.attrs['href']) #打印标签属性中的‘href’的内容
print(tag) #打印a标签的内容
 

HTML遍历:

下行遍历:

属  性

说  明

.contents

子节点的列表,将<tag>所有儿子节点存入列表

.children

子节点的迭代类型,与.contents类似,用于循环遍历儿子节点

.descendants

子孙节点的迭代类型,包含所有子孙节点,用于循环遍历

 r = requests.get('http://python123.io/ws/demo.html')
demo = r.text #demo == url网页代码
soup = BeautifulSoup(demo,'html.parser')
print(soup.head) #获取head标签
print(soup.head.contents) #返回形式是列表,list形式检索head,
print(soup.body.contents) #获得body标签的儿子节点(返回形式是list)
print(len(soup.body.contents)) #利用len测试body标签的节点总数
print(soup.body.contents[1]) #list形式返回,用list方式查看其中的一个节点
#遍历儿子节点
for child in soup.body.children:
print(child)
#遍历子孙节点
for child in soup.body.descendants:
print(child)

上行遍历:

属性

说明

.parent

节点的父亲标签

.parents

节点先辈标签的迭代类型,用于循环遍历先辈节点

 r = requests.get('http://python123.io/ws/demo.html')
demo = r.text #demo == url网页代码
soup = BeautifulSoup(demo,'html.parser')
print(soup.title.parent) #title标签节点的父辈 >>> <head>标签
#上行遍历
for parent in soup.a.parents: #从a标签向上遍历父辈
if parent is None:
print(parent) #先辈如果没有则执行
else:
print(parent.name) #打印先辈的标签名称

平行遍历:

属性

说明

.next_sibling

返回按照HTML文本顺序的下一个平行节点标签

.previous_sibling

返回按照HTML文本顺序的上一个平行节点标签

.next_siblings

迭代类型,返回HTML文本顺序后续所有平行节点标签

.previous_siblings

迭代类型,返回HTML文本顺序后续所有平行节点标签

 r = requests.get('http://python123.io/ws/demo.html')
demo = r.text #demo == url网页代码
soup = BeautifulSoup(demo,'html.parser')
print(soup.a.next_sibling) #a 的下一个平行节点是字符串 >>> 'and'
print(soup.a.next_sibling.next_sibling) #a 的下一个平行标签的在下一个平行标签
print(soup.a.previous_sibling) #a 的上一个平行标签
print(soup.a.previous_sibling.previous_sibling) #>>> None (空信息)
#遍历后续平行节点:
for sibling in soup.a.next_siblings:
print(sibling)
#遍历前序平行节点:
for sibling in soup.a.previous_siblings:
print(sibling)

基于bs4库的HTML格式输出:

prettify()函数:打印标签(HTML格式打印)

 r = requests.get('http://python123.io/ws/demo.html')
demo = r.text
soup = BeautifulSoup(demo,'html.parser')
print(soup.a.prettify()) #输出a标签(HTML格式)
'''
<a class="py1" href="http://www.icourse163.org/course/BIT-268001" id="link1">
Basic Python
</a>
'''
soup = BeautifulSoup('<p>中文</p>','html.parser')
print(soup.p.string) #以[获取<tag>标签的非属性字符串/注释]输出标签
'''
中文
'''
print(soup.p.prettify()) #以HTML格式输出标签
'''
<p>
中文
</p>
'''
 

信息组织和提取:{0.3.py}

信息的标记:

标记后的信息可形成信息组织结构,增加了信息维度

标记后的信息可用于通信

存储或展示

标记的结构与信息一样具有重要价值

标记后的信息更利于程序的理解和运用

HTML的信息标记:

HTML(Hyper Text Markup Language):超文本标记语言;是WWW(World Wide Web)的信息组织方式将声音、图像、视频利用超文本的方式嵌入到文本中;

HTML通过预定义的<>...</>标签形式组织不同类型的信息

信息标记的三种形式:( XML \ JSON \ YAML )

XML (eXtensible Markup Language):扩展标记语言(基于HTML)

JSON(JavsScript Object Notation):有类型的键、值对(key:value)表达方式

YAML(YAML Aint Markup Language):递归的定义;无类型的键值对 Key : Value

三种信息标记方式的比较:(实例)

XML实例

<person>

   <firstName>Tian</firstName>

   <lastName>Song</lastName>

   <address>

        <streetAddr>中关村南大街5号</streetAddr>

        <city>北京市</city>

        <zipcode>100081</zipcode>

   </address>

   <prof>Computer System</prof><prof>Security</prof>

</person>

过实例可以看出,其中有效的信息文本比例并不高,大多数信息被标签占用

JSON实例

{

   “firstName”  : “Tian” ,

   “lastName”  : “Song” ,

   “addresss”   : {                

                   “streetAddr”   : “中关村南大街5号”,

                   “city”         : “北京市”,

                   “zipcode”     : ”100081” 

                }

   “prof”      : [ “Computer System” , “Security” ]

}

JSON通过键值对的方式,定义相关的键<tag>,但无论如何都要用冒号和花括号来区分结构体和键值对

YAML实例   (YAML简洁、明了)

 firstName : Tiam

 lastName : Song

 address :

     streetAddr : 中关村南大街5号

     city      : 北京市

     zipcode   : 100081

 prof  :

 -Computer System

 -security

信息标记

比较

应用

XML

最早的通用信息标记语言,可扩展性好,但繁琐

Internet上的信息交互与传递

JSON

信息有类型,适合程序处理(js),较XML简洁

移动应用云端和节点的信息交互,无注释

YAML

信息无类型,文本信息比例最高,可读性好

各类系统的配置文件,有注释易读

信息提取的一般方法:

方法一:完整解析信息的标记形式,再提取关键信息。

XML JSON YAML_需要标记解析器,例如:bs4库的标签树遍历

优点:信息解析准确

缺点:提取过程繁琐,速度慢

方法二:无视标记形式,直接搜索关键信息。

搜索 对信息的文本查找函数即可

优点:提取过程简洁,速度较快

缺点:提取结果准确性与信息内容相关(缺乏)

融合方法结合形式解析与搜索方法,提取关键信息

XML JSON YAML + 搜索 >>> 需要标记解析器及文本查找函数

实例:

 import requests
from bs4 import BeautifulSoup
'''#提取HTML中所有的URL链接
1、搜索到所有的<a>标签(a标签的内容即url)
2、解析<a>标签格式,提取href后的链接内容
''' r = requests.get('http://python123.io/ws/demo.html')
demo = r.text
soup = BeautifulSoup(demo,'html.parser')
for link in soup.find_all('a'): #查找demo中的<a>标签
print(link.get('href')) #在<a>标签中查找“href”函数 '''
结果:
http://www.icourse163.org/course/BIT-268001
http://www.icourse163.org/course/BIT-1001870001
'''
 

Beautiful Soup库的方法:

bs4.element.Tag:标签类型;

方法

<>.find_all (name,attrs,recursive,string,**kwargs)

说明

可以在soup的变量中去查找里边的信息

参数

返回一个列表类型,存储查找的结果

参数

说明

提升

name

对标签的名称的检索字符串

如果对多个内容检索,则可以用list方式

attrs

对标签属性值的检索字符串

可标注属性索引

recursive

是否对子孙全部检索(默认True)

False则只对儿子层检索

string

<>...</>中字符串区域的检索字符串

string=’....’

简短检索

<tag>(...) 等价于 <tag>.find_all(..)

soup (...) 等价于  soup.find_all(..)

扩展方法

方法

说明

<>.find()

搜索且只返回一个结果,字符串(string)类型,

<>.find_parents()

在先辈节点中搜索,返回list类型,

<>.find_parent()

在先辈节点中返回一个节点,string类型,

<>.find_next_siblings()

在后续平行节点中搜索,返回list类型,

<>.find_next_sibling()

在后续平行节点中返回一个结果,string类型

<>.find_previous_siblings()

在前序平行节点中搜索,返回list类型,

<>.find_previous_sibling()

在前序平行节点中返回一个结果,string类型

 

name实例:

 r = requests.get('http://python123.io/ws/demo.html')
demo = r.text
soup = BeautifulSoup(demo,"html.parser")
print(soup.find_all('a')) #list形式返回soup(文本)中的标签字符串(检索a标签)
print(soup.find_all(['a','b']))
for tag in soup.find_all(True): #遍历soup中的所有标签
print(tag.name) #打印(获得)所有标签的name(名称)!!
'''
[<a class="py1" href="http://www.icourse163.org/course/BIT-268001"
id="link1">Basic Python</a>, <a class="py2" href="http://www.icourse163.org
/course/BIT-1001870001" id="link2">Advanced Python</a>]
[<b>The demo python introduces several python courses.</b>, <a class="py1"
href="http://www.icourse163.org/course/BIT-268001" id="link1">Basic
Python</a>, <a class="py2" href="http://www.icourse163.org/course/
BIT-1001870001" id="link2">Advanced Python</a>]
html
head
title
body
p
b
p
a
a
'''#结果

attrs实例:

 r = requests.get('http://python123.io/ws/demo.html')
demo = r.text
soup = BeautifulSoup(demo,'html.parser')
print(soup.find_all('p', 'course')) #返回带有course属性的P标签
print(soup.find_all(id='link1')) #返回ID属性==link1的内容 ‘’’ [<p class="course">Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses: <a class="py1" href="http://www.icourse163.org/course/BIT-268001" id="link1">Basic Python</a> and <a class="py2" href="http://www.icourse163.org/course/BIT-1001870001" id="link2">Advanced Python</a>.</p>] [<a class="py1" href="http://www.icourse163.org/course/BIT-268001" id="link1">Basic Python</a>] ‘’’

recursive实例:

 r = requests.get('http://python123.io/ws/demo.html')
demo = r.text
soup = BeautifulSoup(demo,'html.parser')
print(soup.find_all('a')) #检索a标签
print(soup.find_all('a',recursive=False))#返回一个空列表,说明a的下层节点没有a标签(False下只检索一层(儿子层))

string实例:

 r = requests.get('http://python123.io/ws/demo.html')
demo = r.text
soup = BeautifulSoup(demo,'html.parser')
print(soup) #输出经过解析器解析的完整HTML代码
print(soup.find_all(string = 'Basic Python')) #列表返回检索到的字符串信息

中国大学排名定向爬虫案例{0.4 bs.py}

 import requests
import bs4
from bs4 import BeautifulSoup
#soup = BeautifulSoup(demo,'html.parser')
def getHTML(url):#标准框架
try:
r = requests.get(url)
r.raise_for_status()
r.encoding = r.apparent_encoding
return (r.text)
except:
print("链接爬取失败") def uitHTML(ulist,demo):
soup = BeautifulSoup(demo,'html.parser')
for tr in soup.find('tbody').children: #.find(..)搜索标签结果返回 .children同时遍历儿子(下层)节点
if isinstance(tr,bs4.element.Tag): #检测tr的类型,如果不是标签类型,则过滤(避免遍历到字符串内容)isinstance判断变量类型
tds = tr('td') #等价于tr.find(...)>>>查找 td 标签 (返回的对象是list)
#print(tds) #检验使用:查看tds内容
#tds此时得到了url的HTML中所有tr中td标签的HTML格式(list格式返回)
ulist.append([tds[0].string, tds[1].string, tds[3].string])
#将tds中需要的数据(只提取.string>>字符串 区域)存入ulist列表中 def uitUlist(ulist,num):
print("{:^16}\t{:^16}\t{:^16}".format("排名","学校名称","总分"))
for i in range(num):
u = ulist[i]
print("{:^16}\t{:^16}\t{:^16}".format(u[0],u[1],u[2])) def main():
ulist = []
url = "http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html"
demo = getHTML(url)
uitHTML(ulist,demo)
uitUlist(ulist,20) main()

正则表达式:re库:(https://www.cnblogs.com/wangyuyang1016/p/10034868.html)

正则表达式的常用操作符

.

表示任何单个字符

[ ]

字符集,对单个字符给出取值范围

[a,b,c]表示a,b,c ;  [a-z]表示a到z的单个字符

[^]

非字符集,对单个字符给出排除范围

[^a,b,c]表示非a非b非c的单个字符

*

前一个字符0次或无限次扩展

abc*表示ab, abc, abcc, abccc 等

+

前一个字符1次或无限次扩展

abc+表示abc,abcc,abccc 等

?

前一个字符0次或1次扩展

abc?表示ab,abc

|

左右表达式任意一个

abc|def表示abc或def

{m}

扩展前一个字符m次

ab{2}c表示abbc

{m,n}

扩展前一个字符m至n次(含n)

ab{1,2}c表示abc、abbc

^

匹配字符串开头

^abc表示abc且在一个字符串的开头

$

匹配字符串结尾

abc$表示abc且在一个字符串的结尾

( )

分组标记,内部只能使用 | 操作符

(abc)表示abc,(abc|def)表示abc、def

\d

数字,等价于[0-9]

\w

单词字符,等价于[A-Za-z0-9]

re库主要功能函数

re.search()

在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象

re.match()

在一个字符串的开始位置起匹配正则表达式,返回match对象

re.findall()

搜索字符串,以列表类型返回全部能匹配的子串

re.split()

将一个字符串按照正则表达式匹配结果进行分割,返回list类型

re.finditer()

搜索字符串,返回一个匹配结果的迭代(iterable)类型,每个iterable元素是match对象

re.sub()

在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串

功能函数详讲:

语法

re.search ( pattern , string , flags=0 )

参数

说明

pattern

正则表达式的字符串或原生字符串表示

string

待匹配的字符串(string)

flags

正则表达式使用时的控制标记

flags控制标记

re.I

忽略正则表达式的大小写

re.M

(多行匹配)的 ^ 操作符能够将给定的字符串的每行当作匹配开始

re.S

正则中的 . 操作符能够匹配所有字符

语法

re.match ( pattern , string , flags=0 )

参数

说明

pattern

正则表达式的字符串或原生字符串表示

string

待匹配的字符串(string)

flags

正则表达式使用时的控制标记

flags控制标记

re.I

忽略正则表达式的大小写

re.M

(多行匹配)的 ^ 操作符能够将给定的字符串的每行当作匹配开始

re.S

正则中的 . 操作符能够匹配所有字符

语法

re.findall ( pattern , string , flags=0 )

参数

说明

pattern

正则表达式的字符串或原生字符串表示

string

待匹配的字符串(string)

flags

正则表达式使用时的控制标记

flags控制标记

re.I

忽略正则表达式的大小写

re.M

(多行匹配)的 ^ 操作符能够将给定的字符串的每行当作匹配开始

re.S

正则中的 . 操作符能够匹配所有字符

语法

re.split ( pattern , string , maxsplit=0 , flags=0 )

参数

说明

pattern

正则表达式的字符串或原生字符串表示

string

待匹配的字符串(string)

maxsplit

最大分割数,剩余部分作为最后一个元素输出

flags

正则表达式使用时的控制标记

flags控制标记

re.I

忽略正则表达式的大小写

re.M

(多行匹配)的 ^ 操作符能够将给定的字符串的每行当作匹配开始

re.S

正则中的 . 操作符能够匹配所有字符

语法

re.finditer ( pattern , string , flags=0 )

参数

说明

pattern

正则表达式的字符串或原生字符串表示

string

待匹配的字符串(string)

flags

正则表达式使用时的控制标记

flags控制标记

re.I

忽略正则表达式的大小写

re.M

(多行匹配)的 ^ 操作符能够将给定的字符串的每行当作匹配开始

re.S

正则中的 . 操作符能够匹配所有字符

语法

re.sub ( pattern , repl , string , count=0 , flags=0 )

参数

说明

pattern

正则表达式的字符串或原生字符串表示

repl

替换匹配字符串的字符串

string

待匹配的字符串(string)

count

替换匹配的最大次

flags

正则表达式使用时的控制标记

flags控制标记

re.I

忽略正则表达式的大小写

re.M

(多行匹配)的 ^ 操作符能够将给定的字符串的每行当作匹配开始

re.S

正则中的 . 操作符能够匹配所有字符

re.compile():面向对象用法(操作):

语法

regex = re.compile( pattern , flags = 0)

说明

·将正则表达式的字符串形式编译成正则表达式对象(object)

pattern

正则表达式的字符串或原生字符串表示(正则表示方法)

flags

正则表达式使用时的控制标记

match = regex.search(‘string’)  #compile()后的re函数功能使用和原来一样

Match对象的属性

属性

说明

.string

待匹配的文本

.re

匹配时使用的pattern对象(正则表达式)

.pos

正则表达式搜索文本的开始位置

.endpos

正则表达式搜索文本的结束位置

Match对象的方法

方法

说明

.group(0)

获得匹配后的字符串

.start()

匹配字符串在原始字符串的开始位置

.end()

匹配字符串在原始字符串的结束位置

.span()

返回(.start() , .end())

实例:

 import re
match = re.search(r'[1-9]\d{5}','BIT 100081')
#Match对象的属性
print(match.string) #返回匹配时的待匹配字符串
print(match.re) #返回匹配时的re表达式
print(match.pos) #返回匹配的搜索文本开始的位置
print(match.endpos) #返回匹配的搜索文本结束的位置
#Match对象的方法
print(match.group(0)) #返回匹配后的字符串(第一次匹配结果)
print(match.start()) #匹配原始字符串开始的位置
print(match.end()) #匹配原始字符串结束的位置
print(match.span()) #元组形式返回 .start()和.end()

re库的贪婪匹配和最小匹配

 match = re.search(r'PY.*N','PYANBNCNDN') #贪婪匹配(re库默认贪婪匹配,即输出最长的子串匹配)
print(match.group(0))
match = re.search(r'PY.*?N','PYANBNCNDN') #最小匹配
print(match.group(0))

最小匹配操作符

操作符

说明

*?

前一个字符0次或无限次扩展,最小匹配

+?

前一个字符1次或无限次扩展,最小匹配

??

前一个字符0次或1次扩展,最小匹配

{m,n}?

扩展前一个字符m至n次(含n),最小匹配


python_爬虫基础学习的更多相关文章

  1. java网络爬虫基础学习(三)

    尝试直接请求URL获取资源 豆瓣电影 https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort= ...

  2. java网络爬虫基础学习(一)

    刚开始接触java爬虫,在这里是搜索网上做一些理论知识的总结 主要参考文章:gitchat 的java 网络爬虫基础入门,好像要付费,也不贵,感觉内容对新手很友好. 一.爬虫介绍 网络爬虫是一个自动提 ...

  3. 爬虫基础学习 转【http://www.cnblogs.com/huangxincheng/archive/2012/11/08/2759752.html】

    这一篇我们聊聊在页面抓取时应该注意到的几个问题. 一:网页更新 我们知道,一般网页中的信息是不断翻新的,这也要求我们定期的去抓这些新信息,但是这个“定期”该怎么理解,也就是多长时间需要 抓一次该页面, ...

  4. java网络爬虫基础学习(四)

    jsoup的使用 jsoup介绍 jsoup是一款Java的HTML解析器,可直接解析某个URL地址.HTML文本内容.它提供了一套非常省力的API,可通过DOM,css以及类似于Jquery的操作方 ...

  5. java网络爬虫基础学习(二)

    正则表达式 正则表达式写法 含义 \d 代表0-9的任意数字 \D 代表任何非数字字符 \s 代表空格类字符 \S 代表非空格类字符 \p{Lower} 代表小写字母[a-z] \p{Upper} 代 ...

  6. Python BeautifulSoup4 爬虫基础、多线程学习

    针对 崔庆才老师 的 https://ssr1.scrape.center 的爬虫基础练习.Threading多线程库.Time库.json库.BeautifulSoup4 爬虫库.py基本语法

  7. 【学习笔记】第二章 python安全编程基础---python爬虫基础(urllib)

    一.爬虫基础 1.爬虫概念 网络爬虫(又称为网页蜘蛛),是一种按照一定的规则,自动地抓取万维网信息的程序或脚本.用爬虫最大的好出是批量且自动化得获取和处理信息.对于宏观或微观的情况都可以多一个侧面去了 ...

  8. Python_爬虫笔记_2018.3.19

    Python_爬虫_笔记 1.前言 1.1爬虫用途: 网站采集.接口采集(地图(jis 热力学 屋里端口/协议).微信.知乎.) 1.2基本流程:网页下载(requests)+网页解析+爬虫调度 网页 ...

  9. Python爬虫基础

    前言 Python非常适合用来开发网页爬虫,理由如下: 1.抓取网页本身的接口 相比与其他静态编程语言,如java,c#,c++,python抓取网页文档的接口更简洁:相比其他动态脚本语言,如perl ...

随机推荐

  1. 1003 NOIP 模拟赛Day2 城市建设

    题面不好找放一个吧. Description 描述 在有$N$个地级市的H省,政府为了城市开发建设,决定先修路,后造房子,以吸引外来人员.一开始每个城市中有$b_i$个住户,而在两个城市$u,v$之间 ...

  2. WOJ 10 精英选拔

    神仙dp,膜Claris 题意:给一个长度为$n$的数列,求出不超过k次交换后的最大连续子区间和. 发现交换后的最优答案一定是这样的(0和2的长度可以为0)             0        ...

  3. Entity Framework Tutorial Basics(12):Model First

    Model First development with Entity Framework: In the Model First approach, you create Entities, rel ...

  4. 在centos上安装sequoaidb的php驱动

    1:搭建PHP的运行环境 yum install httpd httpd-devel yum install php   php-devel yum install php-gd php-imap p ...

  5. css中设置div水平居中,margin:0px auto没用的情况

    在CSS中加了margin:0px auto;却没有效果,不能实现居中的问题!margin:0px auto;意思就是:上下边界为0,左右根据宽度自适应!就是水平居中的意思.无效的原因是,当你没有设置 ...

  6. mysql--表数据的操作

    插入数据 --测试插入数据 INSERT 表名 VALUES|VALUE(值...)--当没有指定插入顺序的时候按照表的原来的顺序进行插入 INSERT 表名(需要赋值的字段名称) VALUES|VA ...

  7. Java50道经典习题-程序39 分数累加

    题目:编写一个函数,输入n为偶数时,调用函数求1/2+1/4+...+1/n,当输入n为奇数时,调用函数1/1+1/3+...+1/n import java.util.Scanner; public ...

  8. WPARAM和LPARAM的含义

    lParam 和 wParam 是宏定义,一般在消息函数中带这两个类型的参数,通常用来存储窗口消息的参数. LRESULT CALLBACK WindowProc(HWND hwnd, UINT uM ...

  9. 四步走查智能硬件异常Case

    此文已由作者于真真授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 相比于软件,智能硬件产品由于涉及硬件和软件两个端的状态,其异常case要更加错综复杂.由于硬件产品的迭代更新 ...

  10. gRPC官方文档(安全认证)

    文章来自gRPC 官方文档中文版 认证 gRPC 被设计成可以利用插件的形式支持多种授权机制.本文档对多种支持的授权机制提供了一个概览,并且用例子来论述对应API,最后就其扩展性作了讨论. 马上将会推 ...