Python归纳 | 爬虫基础知识
1. urllib模块库
Urllib是python内置的HTTP请求库,urllib标准库一共包含以下子包:
urllib.error 由urllib.request引发的异常类
urllib.parse URL解析组件
urllib.request 用于打开网址的可扩展库。
urllib.response urllib使用的响应类。
urllib.robotparser 加载robots.txt文件并回答有关其他网址可抓取性的问题。
使用urllib库进行post操作,如何建立post数据格式?
1 将数据以字典形式建立
2 利用urllib.parse包的urlencode方法:
urlretrieve()函数
urlretrieve()将远程链接数据下载到本地
urlretrieve(url, filename=None, reporthook=None, data=None)
链接、保存本地路径、回调函数、post导服务器的数据
2. Beautiful Soup模块库
Beautiful Soup是一个可以从HTML或XML文件中提取数据的第三方Python库,它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式。
解析器 | 使用方法 | 优势 | 劣势 |
---|---|---|---|
Python标准库 | BeautifulSoup(markup, "html.parser") | Python的内置标准库执行速度适中文档容错能力强 | Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差 |
lxml HTML 解析器 | BeautifulSoup(markup, "lxml") | 速度快文档容错能力强 | 需要安装C语言库 |
html5lib | BeautifulSoup(markup, "html5lib") | 最好的容错性以浏览器的方式解析文档生成HTML5格式的文档 | 速度慢不依赖外部扩展 |
2.1 创建Beautiful Soup对象
from bs4 import BeautifulSoup
#html为解析的页面获得html信息,为方便讲解,在此定义一个html文件
html = """
<html>
<head>
<title>CRIME</title>
</head>
<body>
<p class="title" name="blog"><b>My Blog</b></p>
<li><!--注释--></li>
<a href="http://xxxxx/xxxx/xxxx/xxxx/xxxx" class="sister" id="link1">Html举例1</a><br/>
<a href="http://xxxxx/xxxx/xxxx/xxxx/xxxx" class="sister" id="link2">Html举例1</a><br/>
<a href="http://xxxxx/xxxx/xxxx/xxxx/xxxx" class="sister" id="link3">Html举例1</a><br/>
</body>
</html>
创建Beautiful Soup对象
soup = BeautifulSoup(html,'lxml')
还可以使用本地HTML文件来创建对象
soup = BeautifulSoup(open(test.html),'lxml')
使用如下代码格式化输出
print(soup.prettify())
2.2 Beautiful Soup四大对象
Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:
- Tag
- NavigableString
- BeautifulSoup
- Comment
(1) Tag
Tag通俗点讲就是HTML中的一个个标签,例如
<title>CRIME</title> # title就是HTML标签,标签加入里面包括的内容就是Tag
用 Beautiful Soup 获取 Tags
print(soup.title)
#<title>CRIMEi</title>
print(soup.head)
#<head> <title>CRIME</title></head>
print(soup.a)
#<a class="sister" href="http://xxxxx/xxxx/xxxx/xxxx/xxxx" class="sister" id="link1">Html举例1</a>
print(soup.p)
#<p class="title" name="blog"><b>My Blog</b></p>
验证一下这些对象的类型:
print(type(soup.title))
#<class 'bs4.element.Tag'>
Tag有两个重要的属性:name和attrs
name:
print(soup.name)
print(soup.title.name)
#[document]
#title
soup 对象本身比较特殊,它的 name 即为 [document],对于其他内部标签,输出的值便为标签本身的名称。
attrs:
print(soup.a.attrs)
#{'class': ['sister'], 'href': 'http://xxxxx/xxxx/xxxx/xxxx/xxxx', 'id': 'link1'}
把a 标签的所有属性打印输出,得到的类型是一个字典。
如果想要单独获取某个属性,例如我们获取a标签的class叫什么,两个等价的方法如下:
print(soup.a['class'])
print(soup.a.get('class'))
#['sister']
#['sister']
(2) NavigableString
得到了标签的内容,想要获取标签内部的文字,用 .string即可
print(soup.title.string)
#CRIME
(3) BeautifulSoup
BeautifulSoup 对象表示的是一个文档的全部内容。大部分时候,可以把它当作 Tag 对象,是一个特殊的 Tag,我们可以分别获取它的类型,名称,以及属性:
print(type(soup.name))
print(soup.name)
print(soup.attrs)
#<class 'str'>
#[document]
#{}
(4) Comment
Comment对象是一个特殊类型的NavigableString对象,其实输出的内容仍然不包括注释符号,但是如果不好好处理它,可能会对我们的文本处理造成意想不到的麻烦。
print(soup.li)
print(soup.li.string)
print(type(soup.li.string))
#<li><!--注释--></li>
#注释
#<class 'bs4.element.Comment'>
li标签里的内容实际上是注释,但是如果我们利用 .string 来输出它的内容,我们发现它已经把注释符号去掉了,所以这可能会给我们带来不必要的麻烦。
我们打印输出下它的类型,发现它是一个 Comment 类型,所以,我们在使用前最好做一下判断,判断代码如下:
from bs4 import element
if type(soup.li.string) == element.Comment:
print(soup.li.string)
上面的代码中,我们首先判断了它的类型,是否为 Comment 类型,然后再进行其他操作,如打印输出。
2.3 遍历文档数
(1) 直接子节点(不包含孙节点)
contents:
tag的content属性可以将tag的子节点以列表的方式输出:
print(soup.body.contents)
#['\n', <p class="title" name="blog"><b>My Blog</b></p>, '\n', <li><!--注释--></li>, '\n', <a class="sister" href="http://xxxxx/xxxx/xxxx/xxxx/xxxx" class="sister" id="link1">Html举例1</a>, <br/>, '\n', <a class="sister" href="http://xxxxx/xxxx/xxxx/xxxx/xxxx" id="link2">Html举例2</a>, <br/>, '\n', <a class="sister" href="http://xxxxx/xxxx/xxxx/xxxx/xxxx" id="link3">Html举例3</a>, <br/>, '\n']
输出方式为列表,我们可以用列表索引来获取它的某一个元素:
print(soup.body.contents[1])
<p class="title" name="blog"><b>My Blog</b></p>
children:
它返回的不是一个 list,不过我们可以通过遍历获取所有子节点,它是一个 list 生成器对象:
for child in soup.body.children:
print(child)
(2) 搜索文档树(find()、find_all()函数)
find_all方法返回文档中所有匹配对象的列表
find_all(name=None, attrs={}, recursive=True, text=None, limit=None, **kwargs)
find方法返回第一个可匹配的对象,即find_all(...limit=1...)
find(name=None, attrs={}, recursive=True, text=None , **kwargs )
find与find_all除了返回类型不一样,参数用法都一样,以下以find_all为例
name参数:
name 参数可以查找所有名字为 name 的tag,字符串对象会被自动忽略掉。
传递字符:
最简单的过滤器是字符串,在搜索方法中传入一个字符串参数,Beautiful Soup会查找与字符串完整匹配的内容,下面的例子用于查找文档中所有的<a>
标签:
print(soup.find_all('a'))
#['\n', <p class="title" name="blog"><b>My Blog</b></p>, '\n', <li><!--注释--></li>, '\n', <a class="sister" href="http://xxxxx/xxxx/xxxx/xxxx/xxxx" class="sister" id="link1">Html举例1</a>, <br/>, '\n', <a class="sister" href="http://xxxxx/xxxx/xxxx/xxxx/xxxx" id="link2">Html举例2</a>, <br/>, '\n', <a class="sister" href="http://xxxxx/xxxx/xxxx/xxxx/xxxx" id="link3">Html举例3</a>, <br/>, '\n']
传递正则表达式:
如果传入正则表达式作为参数,Beautiful Soup会通过正则表达式的 match() 来匹配内容.下面例子中找出所有以b开头的标签,这表示和<b>
标签都应该被找到
import re
for tag in soup.find_all(re.compile("^b")):
print(tag.name)
#body
#b
#br
#br
#br
传递列表:
如果传入列表参数,Beautiful Soup会将与列表中任一元素匹配的内容返回,下面代码找到文档中所有title标签和b标签:
print(soup.find_all(['title','b']))
#[<title>Jack_Cui</title>, <b>My Blog</b>]
传递True:
True 可以匹配任何值,下面代码查找到所有的tag,但是不会返回字符串节点:
for tag in soup.find_all(True):
print(tag.name)
#html
#head
...
#br
attrs参数:
我们可以通过 find_all() 方法的 attrs 参数定义一个字典参数来搜索包含特殊属性的tag。
print(soup.find_all(attrs={"class":"title"}))
#[<p class="title" name="blog"><b>My Blog</b></p>]
recursive参数:
调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数 recursive=False。
text参数:
通过 text 参数可以搜搜文档中的字符串内容,与 name 参数的可选值一样, text 参数接受字符串 , 正则表达式 , 列表, True。
print(soup.find_all(text="Python3网络爬虫(三):urllib.error异常"))
#['Python3网络爬虫(三):urllib.error异常']
limit参数:
find_all() 方法返回全部的搜索结构,如果文档树很大那么搜索会很慢.如果我们不需要全部结果,可以使用 limit 参数限制返回结果的数量.效果与SQL中的limit关键字类似,当搜索到的结果数量达到 limit 的限制时,就停止搜索返回结果。
文档树中有3个tag符合搜索条件,但结果只返回了2个,因为我们限制了返回数量:
print(soup.find_all("a", limit=2))
#[<a class="sister" href="http://xxxxx/xxxx/xxxx/xxxx/xxxx" id="link1">Html事例1</a>, <a class="sister" href="http://xxxxx/xxxx/xxxx/xxxx/xxxx" id="link2">Html事例2</a>]
attrs参数:
如果传入 class 参数,Beautiful Soup 会搜索每个 class 属性为 title 的 tag 。kwargs 接收字符串,正则表达式
print(soup.find_all(class_="title"))
#[<p class="title" name="blog"><b>My Blog</b></p>]
Python爬虫入门实战
爬虫流程
- 先由urllib的request打开Url得到网页html文档
- 浏览器打开网页源代码分析元素节点
- 通过Beautiful Soup或则正则表达式提取想要的数据
- 存储数据到本地磁盘或数据库(抓取,分析,存储)
练习一:对豆瓣的一个电影排名URL进行抓取
from urllib import request #导入urillib中的request模块
from bs4 import BeautifulSoup #导入bs4中的BeautifulSoup模块
##构造头文件,模拟浏览器访问
url="https://movie.douban.com/chart"
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
page = request.Request(url,headers=headers) #用urllib的request打开Url得到网页html文档
page_info = request.urlopen(page).read().decode('utf-8') #打开Url,获取HttpResponse返回对象并读取其ResposneBody
soup = BeautifulSoup(page_info, 'html.parser') # 将获取到的内容转换成BeautifulSoup格式,并将html.parser作为解析器
titles = soup.find('div','indent') # 查找所有div标签中class='indent'的Tag
for t in titles.find_all('a',class_="nbg"): # 查找所有a标签中class=nbg的Tag(隐藏的class属性不解!!!!)
print(t.attrs['title']) # 打印查找到的每一个a标签中的title
print(t.attrs['href']) #打印查找到的每一个a标签中的文章链接href
#在磁盘以只写的方式打开/创建一个名为 articles 的txt文件
#open()是读写文件的函数,with语句会自动close()已打开文件
with open(r"D:\BaiduYunDownload\articles.txt","w") as file:
for t in titles.find_all('a',class_="nbg"):
file.write(t.attrs['title']+'\n')
file.write(t.get('href')+'\n\n')
练习二:爬取169图片并保存到本地
from urllib import request #导入urillib中的request模块
from bs4 import BeautifulSoup #导入bs4中的BeautifulSoup模块
import re
import time
def getImg(url):
##构造头文件,模拟浏览器访问
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
page = request.Request(url,headers=headers)
#用request打开Url,获取HttpResponse返回对象并读取其ResposneBody
html=request.urlopen(page).read().decode('utf-8','ignore')
#将获取到的内容转换成BeautifulSoup格式,并将html.parser作为解析器
soup = BeautifulSoup(html, 'html.parser')
links=soup.find('div',class_='big_img') #获取标签为div,class属性为big_img的对象
for link in links.find_all('img',src=re.compile(r'.jpg$')): #获取标签为img,无class属性,以.jpg结尾的src属性列表并迭代对象
path = r'D:\BaiduYunDownload\IMG'
request.urlretrieve(link.attrs['src'],path+'\%s.jpg' % time.time()) #使用request.urlretrieve()直接将所有远程链接数据下载到本地,link.attr返回的是一个属性字典
if __name__=="__main__":
url=input("请输入网址:")
n=int(input("请输入页数:"))
getImg(url)
for i in range(2,n+1):
url2=url[0:47]+"_"+str(i)+".html"
getImg(url2)
3. Requests模块库
4. lxml库XPath模块
Python爬虫入门实战
import requests
from lxml import etree
import re
url=str(input('请输入网址:'))
file_name=str(input('请输入文件夹名:'))
headers = { "User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36" }
count=0
flag=1
while flag:
req =requests.get(url,headers=headers).content
html=etree.HTML(req)
element =html.xpath('//p/img/@src')
for i in element:
r = requests.get(i)
count=count+1
print('下载第{}张'.format(count))
with open("D:/BaiduYunDownload/IMG/"+str(file_name)+str(count)+".jpg", "wb") as f:
f.write(r.content)
judge=html.xpath('//ul[@class="pagelist"]/li[last()]/@class')
if judge==['thisclass']:
flag=0
urls=html.xpath('//div/ul[@class="pagelist"]/li[last()]/a/@href')[0]
url=url[:46]+urls
print("完成")
Python归纳 | 爬虫基础知识的更多相关文章
- 自学Python四 爬虫基础知识储备
首先,推荐两个关于python爬虫不错的博客:Python爬虫入门教程专栏 和 Python爬虫学习系列教程 .写的都非常不错,我学习到了很多东西!在此,我就我看到的学到的进行总结一下! 爬虫就是 ...
- Python进阶----计算机基础知识(操作系统多道技术),进程概念, 并发概念,并行概念,多进程实现
Python进阶----计算机基础知识(操作系统多道技术),进程概念, 并发概念,并行概念,多进程实现 一丶进程基础知识 什么是程序: 程序就是一堆文件 什么是进程: 进程就是一个正在 ...
- Python开发(一):Python介绍与基础知识
Python开发(一):Python介绍与基础知识 本次内容 一:Python介绍: 二:Python是一门什么语言 三:Python:安装 四:第一个程序 “Hello world” 五:Pytho ...
- python 爬虫基础知识一
网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本. 网络爬虫必备知识点 1. Python基础知识2. P ...
- Python 爬虫基础知识
requests Python标准库中提供了:urllib.urllib2.httplib等模块以供Http请求,但是,它的 API 太渣了.它是为另一个时代.另一个互联网所创建的.它需要巨量的工作, ...
- python网络爬虫,知识储备,简单爬虫的必知必会,【核心】
知识储备,简单爬虫的必知必会,[核心] 一.实验说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubuntu Linux环境,实验中会用到桌 ...
- python从爬虫基础到爬取网络小说实例
一.爬虫基础 1.1 requests类 1.1.1 request的7个方法 requests.request() 实例化一个对象,拥有以下方法 requests.get(url, *args) r ...
- Python扫描器-爬虫基础
0x1.基础框架原理 1.1.爬虫基础 爬虫程序主要原理就是模拟浏览器发送请求->下载网页代码->只提取有用的数据->存放于数据库或文件中 1.1.基础原理 1.发起HTTP请求 2 ...
- 基于Python的Flask基础知识
Flask简介 Flask 是一个使用 Python 编写的轻量级 Web 应用程序框架.Armin Ronacher带领一个名为Pocco的国际Python爱好者团队开发了Flask. 下面我们简单 ...
随机推荐
- SQL之DCL
DCL(Data Control Language)数据库控制语言 授权,角色控制等GRANT 授权REVOKE 取消授权 1)授权命令 grant,语法格式(SQL语句不区分大小写):Grant ...
- 《PRC:更新项目汇总额》报错
请求报红,日志如下: +---------------------------------------------------------------------------+ 项目: Version ...
- js任意位数求和
<script> //任意位数求和 function sum(){ if(arguments.length==1) { console.log(arguments[0]) return; ...
- WINDOWS权限大牛们,请进
大家好, 我遇到一个问题,我的一台windows7去访问另一个电脑的共享,输入账号密码后,老是说密码不正确.而其他电脑去访问共享,密码账号密码后都OK 我想知道原因是什么?
- React+gulp+browserify模块化开发
阅读本文需要有React的基础知识,可以在React 入门实例教程和React中文官网进行基础学习. 没有React基础也可以学习本文,本文主要不是学习React,而是gulp+browserify进 ...
- MarkdownPad基于语法示例
博客园 [有道] (https://www.zybuluo.com/mdeditor#) [Markdown语法教学链接] (https://www.cnblogs.com/chimoxuanzhi/ ...
- 多线程《七》信号量,Event,定时器
一 信号量 信号量也是一把锁,可以指定信号量为5,对比互斥锁同一时间只能有一个任务抢到锁去执行,信号量同一时间可以有5个任务拿到锁去执行,如果说互斥锁是合租房屋的人去抢一个厕所,那么信号量就相当于一群 ...
- 移动端头部适配 meta基础知识
meta基础知识 H5页面窗口自动调整到设备宽度,并禁止用户缩放页面 <meta name="viewport" content="width=device-wid ...
- Windows bat脚步同步时间
@echo onnet stop w32timew32tm /unregisterw32tm /registernet start w32timew32tm /config /manualpeerli ...
- php 中 include 与 require 的区别
以下内容转自:https://blog.csdn.net/hsd2012/article/details/51089785 网上太多关于php中include与require区别.其实说的都是经不起验 ...