目录
1.requests模块
通过requests模块爬取指定网站中的图片并保存到本地目录中。
import re import uuid from pathlib import Path import requests resp = requests.get('http://www.deskcity.org/animals/') # 设置编码格式 resp.encoding = "utf-8" # 通过re正则表达式查找网页中的images图片信息 rs = re.findall(r'<img src = "(.*?)"',resp.text) # 循环遍历所有的图片 for url in rs: # 定义文件名 filename = str(uuid.uuid4())+'.jpg' print(f"正在下载【{filename}】图片,请稍等。。。") # 定义Path对象 p = Path("imgs\\"+filename) # 创建文件 p.touch() # 下载文件 f = requests.get(url) # 读写文件保存图片 p.write_bytes(f.content)
上述案例采用的是同步方式下载图片,效率太低。异步方式如下(线程):
# target为目标函数;args中传入的是download函数的参数url threading.Thread(target=download,args=(url,)).start()
注意:args
为元组格式,如果传入一个参数注意后面必须跟着一个逗号;线程配置完毕之后记得调用start方法启动线程。
2.Beautiful Soup
2.1.什么是Beautiful Soup
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库。它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间.
2.2.解析器
Beautiful Soup
支持Python
标准库中的HTML解析器,还支持一些第三方的解析器:
解析器 | 使用方法 | 优势 | 劣势 |
---|---|---|---|
Python标准库 | BeautifulSoup(markup, "html.parser") | Python的内置标准库执行速度适中文档容错能力强 | Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差 |
lxml HTML 解析器 | BeautifulSoup(markup, "lxml") | 速度快文档容错能力强 | 需要安装C语言库 |
lxml XML 解析器 | BeautifulSoup(markup, ["lxml-xml"])``BeautifulSoup(markup, "xml") | 速度快唯一支持XML的解析器 | 需要安装C语言库 |
html5lib | BeautifulSoup(markup, "html5lib") | 最好的容错性以浏览器的方式解析文档生成HTML5格式的文档 | 速度慢不依赖外部扩展 |
2.3.安装与配置
# 安装requests模块 pip install requests==2.10.0 # 安装beautiful soup4 pip install bs4 # 安装lxml解析器 pip install lxml
2.4.快速入门
将代码
index.html
文件复制到python
项目中即可。<html> <head><title>title</title></head> <body> <div> <p class="aa" id="username">hello world</p> <p>hello python</p> <p>hello girl</p> <input class="aa" type="text" value="hehe"/> </div> </body> </html>
2.4.1 解析数据
标签
每个tag都有自己的名字,通过
soup.name
来获取标签。# 获取p标签 p = soup.p print(p) # 获取title标签 title = soup.title print(title)
注意:如果有多个相同的标签,则会返回第一个。
属性
一个标签可能有很多个属性。例如:标签 <b class="boldest">
有一个 class
的属性,值为 boldest
。标签的属性的操作方法与字典相同。
获取指定标签的单一属性,类似字典方式
# 获取p标签的class属性 attrs = soup.p["class"] print(attrs)
注意:最常见的多值的属性是 class (一个标签可以有多个
CSS
的class
). 还有一些属性rel
,rev
,accept-charset
,headers
,accesskey
. 在Beautiful Soup
中多值属性的返回类型是list
。
获取指定标签的单一属性,通过
attrs
方式# 通过attrs获取p标签的id属性 id_ = soup.p.attrs["id"] print(id_)
获取指定标签的所有属性:
# 获取指定标签的所有属性 p_attrs = soup.p.attrs print(p_attrs)
标签内容
通过
.text
和.string
获取标签节点的内容,也可以通过.strings
获取标签节点下的所有内容。# 获取单个标签的内容 text = soup.p.text print(text) print(soup.p.string) # 获取该标签下所有的内容,返回generator生成器 strings = soup.div.strings for st in strings: print(st)
2.4.2 遍历文档树
子节点
标签小技巧获取层级子节点:
# tag小技巧获取层级子节点 print(soup.body.div.p)
.contents
:将标签的子节点以列表的方式输出# 获取div标签下的所有子节点 print(soup.body.div.contents) # 获取div标签下的第二个子节点 print(soup.body.div.contents[1]) # 获取div标签下的第二个子节点的标签名 print(soup.body.div.contents[1].name) # 获取div标签下的第二个子节点的所有属性 print(soup.body.div.contents[1].attrs)
.children
:对标签的子节点进行循环# 获取div下的的子节点 children = soup.body.div.children print(children) # 循环打印节点信息 for child in children: print(child)
.descendants
:对所有标签的子孙节点进行递归循环descendants = soup.body.descendants for des in descendants: print(des)
更多内容请查看官网子节点。
父节点
.parent
:获取某个元素的父节点print(soup.p.parent)
.parents
:递归得到元素的所有父辈节点parents = soup.p.parents for p in parents: print(p)
更多内容请查看官网父节点。
兄弟节点
.next_sibling
:获取下级单个兄弟节点print(soup.p.next_sibling.next_sibling)
.previous_sibling
:获取上级单个兄弟节点print(soup.body.previous_sibling.previous_sibling)
注意:在使用.next_sibling
和.previous_sibling
获取单个兄弟节点时,兄弟节点之间存在顿号和换行符的可能!!!
更多内容请查看官网兄弟节点。
2.4.3搜索文档树
find
find方法,语法格式如下:
find( name , attrs , recursive , string , **kwargs )
参数说明:
参数 | 说明 |
---|---|
name | 需要查找的标签名,可以是字符串、正则表达式、列表或True |
attrs | 需要查找的标签的属性,可以是字典类型或关键字参数 |
recursive | 是否递归地搜索子标签,默认为True ,即会搜索所有子孙标签 |
string | 需要查找的标签中包含的文本内容 |
kwargs | 其他属性条件 |
通过
find
方法搜索指定的标签。print(soup.find('p', class_="aa")) print(soup.find('p', class_="aa", id="username"))
注意:class类样式的处理。
True
可以匹配任何值,如下示例返回第一个节点:print(soup.find(True))
更多内容请查看官网。
find_all
find_all()
方法的基本语法如下:find_all(name=None, attrs={}, recursive=True, text=None, limit=None, **kwargs)
参数说明:
参数 | 说明 |
---|---|
name | 需要查找的标签名,可以是字符串、正则表达式、列表或True |
attrs | 需要查找的标签的属性,可以是字典类型或关键字参数 |
recursive | 是否递归地搜索子标签,默认为True ,即会搜索所有子孙标签 |
text | 需要查找的标签中包含的文本内容 |
limit | 限制返回的结果数量,可以传入一个整数值 |
返回值:
-
如果找到满足条件的元素,则返回一个包含这些元素的列表。
-
如果未找到满足条件的元素,则返回一个空列表。
find_add
方法搜索当前标签下所有子节点,并判断是否符合过滤器的条件。all = soup.find_all('p') for a in all: print(a) print(soup.find_all(["p", "input"]))
更多内容请查看官网。
css选择器
Beautiful Soup
支持大部分的CSS
选择器。在Tag
或BeautifulSoup
对象的.select()
方法中传入字符串参数, 即可使用CSS
选择器的语法找到标签:print(soup.select("title")) print(soup.select("body div")) print(soup.select("p.aa"))
3.模块案例
通过
requests
和Beautiful Soup4
模块结合实现小说网站内容爬虫案例。import time from pathlib import Path import bs4 import requests resp = requests.get('http://book.zongheng.com/chapter/1172818/67327837.html') # 设置编码格式 resp.encoding = "utf-8" print(resp.text) # 创建BeautifulSoup soup = bs4.BeautifulSoup(resp.text, 'lxml') # 创建小说文件 p = Path('大明:我重生成为了朱允炆.txt') p.touch() for i in range(10): print(f"正在获取第{i+1}页的小说的内容,请稍等...") # 读写内容 with p.open(mode="a+") as f: # 获取小说标题 title = soup.select("div.title_txtbox")[0].string f.write(f"{title}\n") # 获取小说内容 contents = soup.select("div.conten")[0].strings for c in list(contents)[0:-1]: f.write(f"{c}\n") time.sleep(1) # 获取下一页的地址 url = soup.select("a.nextchapter")[0]["href"] resp = requests.get(url) resp.encoding = "utf-8" soup = bs4.BeautifulSoup(resp.text, 'lxml')
4.思维导图
----------------------------------------------------------------------------------------♥-------------------------------------------------------------------------------------
往期Python内容:
标签:网页,获取,Python,标签,soup,print,解析,节点 From: https://blog.csdn.net/Love_Ban/article/details/139142443