小马哥正在为Python的所有常见知识进行汇总,更会有大量实战项目
点击--> 全栈工程师养成---Python内容导航页 <--查看所有Python内容
Python与正则表达式
URLlib模块的使用
使用爬虫进行数据采集的主要流程:
发送请求 -> 接收响应 -> 解析数据 -> 存储数据 [-> 数据分析 -> 数据可视化] 加上括号里面内容属于数据数据分析的范畴
Python和Java类似, 强大之处已经不局限于一门语言本身, 而是背后有强大的"车间"---第三方类库, 准备好了各种不同场景下需要的工具. 例如,以爬虫这种数据采集为例, 我们无需去亲自处理网络通信以及与目标服务器的交互, 这些通用的处理流程, 统统交给已经准备好的类库(urllib,requests,BeautifulSoup等等优秀的模块).
下面就来介绍第一个Python内置的一个HTTP请求库: URLlib, 通过传递给URLlib一个链接, 即可完成模拟浏览器访问站点资源
URLib包下面包含四个模块:
- request 模拟发送请求
- parse 处理URL
- error 异常处理模块
- robotparser 识别网站的robots.txt协议
前三个使用最多
1.发送请求
1.1 发送一个最简单的GET请求(使用urlopen()函数给人民网主页发送一个请求)
# import urllib.request
from urllib import request #这样和上面的导入模块是一样的,下面使用的时候更简洁
response = request.urlopen('http://www.people.com.cn') #返回一个对象
print(response.read().decode('GB2312')) #通过response.read()得到的是字节形式的信息,通过decode()解码显示得到字符串
import urllib.request as req
response = req.urlopen('http://www.baidu.com')
print(response.status)
print(response.getheaders())
print(type(response.getheaders()))
from urllib import request
help(request)
再尝试给一个用来做测试的网站: http://httpbin.org 发送请求
from urllib import request
response = request.urlopen('http://httpbin.org/get')# 打开上面的网址看看网站内容,是一个用来做http测试的网站,会返回各种不同数据用来测试
print(response.read().decode('utf-8'))
1.2 发送一个POST请求: urlopen()函数中data参数的使用
from urllib import request
from urllib import parse
data = bytes(parse.urlencode({'name':'mark'}),encoding='utf-8')
response = request.urlopen('http://httpbin.org/post',data=data)
print(response.read().decode('utf-8'))
1.3 timeout参数
用于设置超时时间(秒),请求超出了设置的这个时间没有得到响应就会抛出异常: URLError
from urllib import request
response = request.urlopen('http://httpbin.org/get',timeout=0.1)
print(response.read().decode('utf-8'))
一般用法: 设置一个超时时间,如果时间超出,跳过这个网页的抓取
1.4 Request对象
通过给Request对象配置一些参数,给urlopen()只传递一个Request对象,实现更灵活的配置
from urllib import request
help(request.Request)
通过上面命令查看Request帮助信息
Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
得到可以封装的参数,下面挨个示例参数的使用:
from urllib import request as req
request = req.Request('http://www.baidu.com')
response = req.urlopen(request)
print(response.read().decode('utf-8'))
from urllib import request as req
try:
request = req.Request('https://www.jianshu.com')
response = req.urlopen(request)
print(response.read().decode('utf-8'))
except:
print('抓取主页,如果不设置header信息会抛出异常...')
from urllib import request as req
try:
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
}
url = 'https://www.jianshu.com'
request = req.Request(url=url,headers=headers)
response = req.urlopen(request)
print(response.read().decode('utf-8'))
except:
print('抓取主页,如果不设置header信息会抛出异常...')
2.解析链接
2.1 urlparse()
urllib的parse模块提供了对URL的解析
使用任何一个url进行分析,不存在的也没有关系,看下面效果
from urllib.parse import urlparse
result = urlparse('http://xxxx:8888/notebooks/Course/PyCourse/Chapter0x_spider_urllib/Untitled.ipynb?username=mayun&age=55')
print(type(result),result)
ParseResult(scheme='http', netloc='xxxx:8888', path='/notebooks/Course/PyCourse/Chapter0x_spider_urllib/Untitled.ipynb', params='', query='username=mayun&age=55', fragment='')
scheme='http',协议
netloc='xxxx:8888',域名
path='/notebooks/Course/PyCourse/Chapter0x_spider_urllib/Untitled.ipynb', 访问路径
params='', 参数
query='username=mayun&age=55',查询条件
fragment=''锚点
2.2 urlunparse()
将一个字符串数组拼接为网址,是上一个函数urlparse()的相反操作
from urllib.parse import urlunparse
#下面列表内容是上一个函数拆解出来的元素
data=['http', 'xxxx:8888', '/notebooks/Course/PyCourse/Chapter0x_spider_urllib/Untitled.ipynb','','username=mayun&age=55','']
print(urlunparse(data))
http://xxxx:8888/notebooks/Course/PyCourse/Chapter0x_spider_urllib/Untitled.ipynb?username=mayun&age=55
注意: urlunparse函数的参数,也就是data这个集合,元素的个数必须满足6个
2.3 urlsplit() 与 urlunsplit()
这两个函数分别与上面两个函数作用类似,看示例说明作用:
from urllib.parse import urlsplit,urlunsplit
result = urlsplit('http://xxxx:8888/notebooks/Course/PyCourse/Chapter0x_spider_urllib/Untitled.ipynb?username=mayun&age=55')
print(result)
data=['http', 'xxxx:8888', '/notebooks/Course/PyCourse/Chapter0x_spider_urllib/Untitled.ipynb','username=mayun&age=55','']
print(urlunsplit(data))
SplitResult(scheme='http', netloc='xxxx:8888', path='/notebooks/Course/PyCourse/Chapter0x_spider_urllib/Untitled.ipynb', query='username=mayun&age=55', fragment='')
http://xxxx:8888/notebooks/Course/PyCourse/Chapter0x_spider_urllib/Untitled.ipynb?username=mayun&age=55
区别: urlsplite()函数相比urlparse()少了 params=''参数,相应的,urlunsplit()函数的参数data,元素个数也是5个
2.4 urljoin()
函数作用: 在基本url的基础上,对缺失的部分进行补充,当然补充的内容由参数给出
2.5 urlencode()
用于构建GET请求参数,作用看示例:
from urllib.parse import urlencode
params={
'name':'xiaomage',
'age':18
}
base_url = 'http://www.baidu.com?'
url = base_url+urlencode(params) #urlencode()作用就是将字典形式的键值对,解析为url的参数形式
print(url)
http://www.baidu.com?name=xiaomage&age=18
作用: 方便构造url的param参数,一般我们程序会将参数用字典表示,这样在拼接带参数的url使用urlencode()就很方便,一步完成转换.
3.处理异常
在爬虫抓取数据的时候,如果程序遇到异常终止运行,这不是我们想看到的,所以捕获异常,然后对其进行处理.URLlib的error模块定义了由request模块产生的异常.包括: URLError与HTTPError异常
from urllib import request,error
# 对异常进行捕获,避免程序因为异常而终止
try:
response = request.urlopen('http://zhinengtianxia.com') #这是一个不存在的网站
except Exception as e:
print(type(e))
4.分析Robots协议
4.1 什么是Robots协议
Robots协议全名: Robots Exclusion Protocol,一般网站都会自带一个robots.txt
存在意义: 告诉爬虫,站点哪些内容是可以抓取的,哪些是不可以抓取的,理论上是一个君子协定.某些搜索引擎面对这个协议,貌似也不遵守,但是我们
样例: 查看资源: https://www.jianshu.com/robots.txt
User-agent: * < - - 描述搜索引擎爬虫的名称
Disallow: /search < - - 指定不允许抓取的目录
Disallow: /convos/
Disallow: /notes/
Disallow: /admin/
Disallow: /adm/
Disallow: /p/0826cf4692f9
Disallow: /p/d8b31d20a867
Disallow: /collections//recommended_authors
Disallow: /trial/
Disallow: /keyword_notes
Disallow: /stats-2017/*
User-agent: trendkite-akashic-crawler
Request-rate: 1/2 # load 1 page per 2 seconds < - - 请求的速度
Crawl-delay: 60 < - - 最低抓取延迟
User-agent: YisouSpider
Request-rate: 1/10 # load 1 page per 10 seconds
Crawl-delay: 60
User-agent: Cliqzbot
Disallow: /
User-agent: Googlebot
Request-rate: 2/1 # load 2 page per 1 seconds
Crawl-delay: 10
小马哥正在为Python的所有常见知识进行汇总,更会有大量实战项目
点击--> 全栈工程师养成---Python内容导航页 <--查看所有Python内容