慕课 爬虫学习 第二周 网络爬虫之规则

第二周 网络爬虫之规则

本周课程导学

​ 内容介绍

单元4: Beautiful Soup库入门

安装

>pip install beautifulsoup4
import requests
from bs4 import BeautifulSoup

r = requests.get('https://python123.io/ws/demo.html')
demo = r.text

soup = BeautifulSoup(demo,"html.parser")
print(soup)
print(soup.prettify())  # 美化输出


基本元素

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

基本元素 说明
Tag 最基本的信息组织单元
Name 名字 .name
Attribute 属性 .attrs
NavigableString 标签内非属性字符串 .string
Comment 标签内字符串的注释部分
import requests
from bs4 import BeautifulSoup

r = requests.get('https://python123.io/ws/demo.html')
demo = r.text

soup = BeautifulSoup(demo,"html.parser")
#print(soup)
print(soup.title)
print(soup.a.name)
print(soup.a.parent.name)
print(soup.a.parent.parent.name)

print('--fengexian-----------------')


tag  = soup.a
print(tag)
print(tag.attrs)
print(tag.attrs['class'])
print(tag.attrs['href'])
print(type(tag.attrs))
print(type(tag))
print('--fengexian-------string----------')

print(soup.a.string)
print(soup.p.string)

print('--fengexian----------注释-------')



D:\develop_study\python\Python38-32\python.exe D:/code_file/first_web/爬虫/慕课/慕课01.py
<title>This is a python demo page</title>
a
p
body
--fengexian-----------------
<a class="py1" href="http://www.icourse163.org/course/BIT-268001" id="link1">Basic Python</a>
{'href': 'http://www.icourse163.org/course/BIT-268001', 'class': ['py1'], 'id': 'link1'}
['py1']
http://www.icourse163.org/course/BIT-268001
<class 'dict'>
<class 'bs4.element.Tag'>
--fengexian-------string----------
Basic Python
The demo python introduces several python courses.
--fengexian----------注释-------

Process finished with exit code 0

基于bs4库的HTML内容遍历方法

下行遍历
属性 说明
.contents 子节点的列表,将所有儿子节点存入列表
.children 子节点的迭代类型,与.contents类似,用于循环遍历儿子节点
.descendants 子孙节点的迭代类型,包含所有子孙节点,用于循环遍历
Python 3.8.2 (tags/v3.8.2:7b3ab59, Feb 25 2020, 22:45:29) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license()" for more information.

>>> import requests
>>> from bs4 import BeautifulSoup
>>> r = requests.get('https://python123.io/ws/demo.html')
>>> demo = r.text
>>> soup = BeautifulSoup(demo,"html.parser")
>>> soup.head
<head><title>This is a python demo page</title></head>

>>> soup.head.contents
[<title>This is a python demo page</title>]
>>> soup.body.contents
['\n', <p class="title"><b>The demo python introduces several python courses.</b></p>, '\n', <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>, '\n']
>>> len(soup.body.contents)
5
>>> soup.body.contents[1]
<p class="title"><b>The demo python introduces several python courses.</b></p>
>>> for child in soup.body.children:
	print(child)

	


<p class="title"><b>The demo python introduces several python courses.</b></p>


<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>


>>> 
上行遍历
属性 说明
.parent 节点的父亲标签
.parents 节点先辈标签的迭代类型,用于循环遍历先辈节点
import requests
from bs4 import BeautifulSoup

r = requests.get('https://python123.io/ws/demo.html')
demo = r.text

soup = BeautifulSoup(demo,"html.parser")

for parent in soup.a.parents:
	if parent is None:
		print(parent)
	else:
		print(parent.name)
p
body
html
[document]

平行遍历
属性 说明
.next_sibling 返回按照HTML文本顺序的下一个平行节点标签
.previous_sibling 返回按照HTML文本顺序的上一个平行节点标签
.next_siblings 迭代类型,返回按照HTML文本顺序的后续所有平行节点标签
.previous_siblings 迭代类型,返回按照HTML文本顺序的前续所有平行节点标签
import requests
from bs4 import BeautifulSoup

r = requests.get('https://python123.io/ws/demo.html')
demo = r.text

soup = BeautifulSoup(demo,"html.parser")

print(soup.a.next_sibling)
print(soup.a.next_sibling.next_sibling)

print(soup.a.previous_sibling)
print(soup.a.previous_sibling.previous_sibling)


for sibling in soup.a.next_siblings:
    print(sibling)

for sibling in soup.a.previous_siblings:
    print(sibling)

基于bs4库的HTML格式输出

.prettify

import requests
from bs4 import BeautifulSoup

r = requests.get('https://python123.io/ws/demo.html')
demo = r.text

soup = BeautifulSoup(demo,"html.parser")

print(soup.prettify) 
print("-----------------------------------------------")
print(soup.a.prettify)

单元小结

单元5:信息组织与提取方法

信息标记的三种形式

​ HTML 超文本标记语言

XML 扩展标记语言 extensible Markup Language

​ 基于HTMl发展而来;

JSON JavaScript Object Notation

​ 有类型的键值对。key:value

​ 键、值 都需要双引号。

​ 移动应用云端和节点的信息通信,无注释。

YAML YAML Ain‘t Markup Language

​ 无类型的键值对 key:value

三种信息标记形式的比较

XML : Internet上的信息交互与传递

JSON: 移动应用云端和节点的信息通信,无注释。

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

信息提取的一般方法

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

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

import requests
from bs4 import BeautifulSoup

r = requests.get('https://python123.io/ws/demo.html')
demo = r.text

soup = BeautifulSoup(demo,"html.parser")

for link in soup.find_all('a'):
    print(link.get('href'))

D:\develop_study\python\Python38-32\python.exe D:/code_file/first_web/爬虫/慕课/慕课01.py
http://www.icourse163.org/course/BIT-268001
http://www.icourse163.org/course/BIT-1001870001

Process finished with exit code 0

基于bs4库的HTML内容查找方法

<>.find_all (name,attrs,recursive,string,**kwargs)
name:对标签名称的检索字符串。
import requests
r = requests.get('https://python123.io/ws/demo.html')
demo = r.text

from bs4 import BeautifulSoup

soup = BeautifulSoup(demo,"html.parser")

print(soup.find_all('a'))

print(soup.find_all(['a','b']))   # 同时查询a和b标签。



for tag in soup.find_all(True):
    print(tag.name)

import re

for tag in soup.find_all(re.compile('b')):  # b  开头的标签
    print(tag.name)

---------------------------------


D:\develop_study\python\Python38-32\python.exe D:/code_file/first_web/爬虫/慕课/慕课01.py
body
b

Process finished with exit code 0

attrs:对标签属性值的检索字符串,可标注属性检索
import requests
r = requests.get('https://python123.io/ws/demo.html')
demo = r.text

from bs4 import BeautifulSoup

soup = BeautifulSoup(demo,"html.parser")

print(soup.find_all('p','course'))


--------------------------------------------------------------------
D:\develop_study\python\Python38-32\python.exe D:/code_file/first_web/爬虫/慕课/慕课01.py
[<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>]

Process finished with exit code 0

print(soup.find_all(id='link1'))


[<a class="py1" href="http://www.icourse163.org/course/BIT-268001" id="link1">Basic Python</a>]

import re

print(soup.find_all(id = re.compile('link')))  # 正则表达式 id以link开头的值


-------------------------------------------
[<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>]


recursive:是否对子孙全部检索,默认True
print(soup.find_all('a'))

print(soup.find_all('a',recursive=False))   # 判断直接子节点有a标签。

------------------------------------

[<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>]

[]
string:<>...</>中字符串区域的检索字符串
print(soup)

print(soup.find_all(string = "Basic Python"))   #必须全部匹配 否则需要正则表达式

import re

print(soup.find_all(string = re.compile("python")))   #包含python的全部检索出来,区分大小写


-------------------------------------------

<html><head><title>This is a python demo page</title></head>
<body>
<p class="title"><b>The demo python introduces several python courses.</b></p>
<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>
</body></html>

['Basic Python']


['This is a python demo page', 'The demo python introduces several python courses.']

soup() 等价于 soup.find_all()
BeautlSoup扩展方法
方法 说明
<>.find() 搜索且只返回一个参数,字符串类型,同 .find_all()参数
<>.find_parents() 在先辈节点中搜索,返回列表类型,同 .find_all()参数
<>.find_parent() 在先辈节点中返回一个结果,字符串类型,同 .find_all()参数
<>.find_next_siblings() 在后续平行节点中搜索,返回列表类型,同 .find_all()参数
<>.find_next_sibling() 在后续平行节点中返回一个结果,字符串类型,同 .find_all()参数
<>.find_previous_siblings() 在前续平行节点中搜索,返回类别类型,同 .find_all()参数
<>.find_previous_sibling() 在前续平行节点中返回一个结果,字符串类型,同 .find_all()参数

单元小结

单元6:中国大学实例排名

中国大学排名定向爬虫 实例介绍

http://www.zuihaodaxue.com/Greater_China_Ranking2019_0.html

程序的结构设计

步骤1:从网络上获取大学排名网页内容 getHTMLText()

步骤2:提取网页内容中信息到合适的数据结构 fillUnivList()

步骤3:利用数据结构展示并输出结果 printUnivList()

中国大学排名定向爬虫 实例编写

import requests
from bs4 import BeautifulSoup
import bs4

def getHTMLText(url):
    try:
        r = requests.get(url,timeout =30)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return ""

def fillUnivList(ulist,html):
    soup = BeautifulSoup(html,"html.parser")
    for tr in soup.find('tbody').children:
        if isinstance(tr,bs4.element.Tag):
            tds = tr('td')
            ulist.append([tds[0].string,tds[1].string,tds[3].string])

def printUnivList(ulist,num):
    print("{:^10}\t{:^15}\t{:^10}".format("排名","学校","得分"))
    for i in range(num):
        u = ulist[i]
        print("{:^10}\t{:^15}\t{:^10}".format(u[0],u[1],u[2]))



def main():
    uinfo =[]
    url = 'http://www.zuihaodaxue.com/Greater_China_Ranking2019_0.html'
    html = getHTMLText(url)
    fillUnivList(uinfo,html)
    printUnivList(uinfo,20)  # 20个大学

main()


-------------------------------------------------------------

D:\develop_study\python\Python38-32\python.exe D:/code_file/first_web/爬虫/慕课/慕课01.py
    排名    	      学校       	    得分    
    1     	   清华大学(北京)    	    大陆    
    2     	     北京大学      	    大陆    
    3     	    香港中文大学     	    香港    
    4     	     浙江大学      	    大陆    
    5     	     香港大学      	    香港    
    6     	   中国科学技术大学    	    大陆    
    7     	    上海交通大学     	    大陆    
    8     	     复旦大学      	    大陆    
    9     	   清华大学(新竹)    	    台湾    
    10    	     台湾大学      	    台湾    
    11    	    北京师范大学     	    大陆    
    12    	    香港城市大学     	    香港    
    13    	    香港科技大学     	    香港    
    14    	     南京大学      	    大陆    
    15    	    华中科技大学     	    大陆    
    16    	   中山大学(广州)    	    大陆    
    17    	    香港理工大学     	    香港    
    18    	   交通大学(新竹)    	    台湾    
    19    	    哈尔滨工业大学    	    大陆    
    20    	    澳门科技大学     	    澳门    

Process finished with exit code 0

中国大学排名定向爬虫 实例优化

def printUnivList(ulist,num):
    tplt = "{0:^10}\t{1:{3}^20}\t{2:^10}"
    print(tplt.format("排名","学校","得分",chr(12288)))
    for i in range(num):
        u = ulist[i]
        print(tplt.format(u[0],u[1],u[2],chr(12288)))


--------------------------------------------------------

D:\develop_study\python\Python38-32\python.exe D:/code_file/first_web/爬虫/慕课/慕课01.py
    排名    	         学校         	    得分    
    1     	      清华大学(北京)      	   100    
    2     	        北京大学        	   80.5   
    3     	       香港中文大学       	   71.0   
    4     	        浙江大学        	   66.1   
    5     	        香港大学        	   62.0   
    6     	      中国科学技术大学      	   61.4   
    7     	       上海交通大学       	   58.9   
    8     	        复旦大学        	   56.8   
    9     	      清华大学(新竹)      	   56.5   
    10    	        台湾大学        	   54.8   
    11    	       北京师范大学       	   53.9   
    12    	       香港城市大学       	   50.1   
    13    	       香港科技大学       	   49.8   
    14    	        南京大学        	   46.9   
    15    	       华中科技大学       	   44.3   
    16    	      中山大学(广州)      	   43.9   
    17    	       香港理工大学       	   43.5   
    18    	      交通大学(新竹)      	   42.5   
    19    	      哈尔滨工业大学       	   42.0   
    20    	       澳门科技大学       	   41.9   

Process finished with exit code 0

单元小结

posted @ 2020-04-14 11:30  前进小蜗牛  阅读(199)  评论(0编辑  收藏  举报