第一课:网络爬虫准备
一、本课知识路线
1、Requests框架:自动爬取HTML页面与自动网络请求提交
2、robots.txt:网络爬虫排除标准
3、BeautifulSoup框架:解析HTML页面
4、Re框架:正则框架,提取页面关键信息
5、Scrapy框架:网络爬虫原理介绍,专业爬虫框架介绍
#抓取百度页面 import requests r = requests.get('http://www.baidu.com') print(r.status_code) #状态码,抓取成功200 r.encoding = 'utf-8' #把编码改为utf-8 print(r.text) #输出抓取内容
二、Requests库的七个主要方法
1、requests.request(method,url,**kwargs):构造一个请求,支持以下方法的基础方法
method:请求方式,对应GET\POST\PUT\HEAD\PATCH\delete\OPTIONS7种
url:获取的页面的URL连接
**kwargs:控制访问的参数,共13个(可选):
1、params:字典或字节序列,作为参数增加到url中
import requests url = 'http://httpbin.org/post' payload = {'key1':'value1','key2':'value2'} r = requests.get(url, params = payload) print(r.url) #http://httpbin.org/post?key1=value1&key2=value2
2、data:字典、字节序列或文件对象,作为Request的内容
3、json:JSON格式数据,作为Request的内容
4、headers:字典,HTTP定制头
import requests url = 'http://httpbin.org/post' payload = {'user-agent':'Chrome/10'} r = requests.request('POST',url,headers=payload) #修改agent
5、cookies:字典或CookieJar,Request中的cookie
6、auth:元组,支持HTTP认证功能
7、files:字典类型,传输文件
import requests url = 'http://httpbin.org/post' fs = {'file':open('data.xls','rb')} r = requests.request('POST',url,files=fs) #向页面传输文件
8、timeout:设定超时时间,秒为单位
import requests url = 'http://httpbin.org/post' r = requests.request('GET',url,timeout = 10)
9、proxies:字典类型,设定访问代理服务器,可以增加登录认证
import requests url = 'http://httpbin.org/post' pxs = {'http':'http://user:pass@10.10.10.1:1234','http':'http://10.10.10.1:1234'} #设置两个代理服务器 r = requests.request('GET',url,proxies=pxs)
10、allow_redirects:True/False,默认为True,重定向开关
11、stream:True/False,默认为True,获取内容立即下载开关
12、verify:True/False,默认为True,认证SSL证书开关
13、cert:本在SSL证书路径
2、requests.get(url,params=None,**kwargs):获取HTML页面的主要方法,对应HTTP的GET
url:获取页面的url链接
params:url中额外参数,字典或字节流格式,可选
**kwargs:12控制访问参数,可选
1、构造一个向服务器请求资源的Request对象
2、函数返回一个包含服务器资源的Response对象
说明:Response对象
import requests response = requests.get('http://www.baidu.com') print(response.status_code) #200 print(response.encoding) #ISO-8859-1 print(response.apparent_encoding) #utf-8 response.encoding = response.apparent_encoding print(response.headers)
Response对象属性
1、r.status_code:HTTP请求的返回状态,200表示连接成功,404表示失败或者其他
2、r.text:HTTP响应内容的字符串形式,即url对应的页面内容
3、r.encoding:从HTTP header中猜测的响应内容编码方式
4、r.apparent_encoding:从内容中分析出的响应内容编码方式(备选编码方式)
5、r.content:HTTP响应内容的二进制形式
3、requests.head(url,**kwargs(13个参数)):获取HTML页面的头部信息方法,对应HTTP的HEAD
import requests url = 'http://www.baidu.com' r = requests.head(url) print(r.headers) print(r.text) #无输出内容
4、requests.post(url,data=None,json=None,**kwargs(11个可选参数)):向HTML页面提交POST请求方法,对应HTTP的POST
import requests url = 'http://httpbin.org/post' payload = {'key1':'value1','key2':'value2'} r = requests.post(url, data = payload) #向URL POST一个字典,自动编码为form表单 print(r.text)
import requests url = 'http://httpbin.org/post' r = requests.post(url, data = 'abc') #向URL POST一个字符串,自动编码为data
print(r.text)
5、requests.put(url,data=None,**kwargs(12可选参数)):向HTML页面提交PUT请求方法,对应HTTP的PUT
put方法与post方法一样,区别在于put方法会把原有数据覆盖
6、requests.patch(url,data=None,**kwargs(12可选参数)):向HTML页面提交局部修改请求方法,对应HTTP的PATCH
7、requests.delete(url,**kwargs(13个可选参数)):向HTML页面提交删除请求方法,对应HTTP的DELETE
三、Requests库的异常
异常 | 说明 |
requests.ConnectionError | 网络连接错误异常,如DNS查询失败、拒绝连接等 |
requests.HTTPError | HTTP错误异常 |
requests.URLRequired | URL缺失异常 |
requests.TooManyRedirects | 超过最大重定向次数,产生重定向异常 |
requests.ConnectTimeout | 连接运程服务超时异常 |
requests.Timeout | 请滶URL起时,产生超时异常 |
r.raise_for_status():Requests异常方法,返回200则抓取正常,如果不是200,产生异常requests.HTTPError
四、爬虫网页的通用代码框架
import requests def getHTMLText(url): try: response = requests.get(url,timeout=30) #返回Response对象 response.raise_for_status() #如果状态不是200,则产生HTTPError异常,跳转运行except处代码 response.encoding = response.apparent_encoding #保证页面编码正确 return response.text #返回抓取内容 except: return '产生异常!' if __name__ == '__main__': url = 'http://www.baidu.com' print(getHTMLText(url))
五、HTTP协议:Hypertext Transfer Protocol,超文本传输协议
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位置存储的资源 |
六、作业:Requests库的爬取性能分析
尽管Requests库功能很友好、开发简单(其实除了import外只需一行主要代码),但其性能与专业爬虫相比还是有一定差距的。请编写一个小程序,“任意”找个url,测试一下成功爬取100次网页的时间。(某些网站对于连续爬取页面将采取屏蔽IP的策略,所以,要避开这类网站。)
import requests import time def getHTMLText(url): try: r = requests.get(url, timeout = 10) r.raise_for_status() r.encoding = r.apparent_encoding return r.text except: return 'Error'
if __name__ == '__main__': url = 'http://www.bilibili.com' print('start the test:') start_time = time.clock() for i in range(100): getHTMLText(url) end_time = time.clock() print('Total runing time:%s' %(end_time-start_time)) #Total runing time:114.73649717934875
#作业 #1、爬虫京东 import requests url = 'https://item.jd.com/2357091.html' try: r = requests.get(url) r.raise_for_status() r.encoding = r.apparent_encoding print(r.text[:1000]) print(r.request.headers) #{'User-Agent': 'python-requests/2.13.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'} except: print('Error') #2、爬虫amzon import requests url = 'https://www.amazon.cn/dp/B004DCV1FO' try: kv = {'User-Agent':'Mozilla/5.0'} r = requests.get(url) r.raise_for_status() r.encoding = r.apparent_encoding print(r.status_code) print(r.request.headers) r = requests.get(url,headers = kv) print(r.status_code) print(r.request.headers) except: print(r.status_code) /* 200 {'User-Agent': 'python-requests/2.13.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'} 200 {'User-Agent': 'Mozilla/5.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'} */ #3、向百度与其360提交搜索关键字 import requests try: r = requests.get('http://www.baidu.com/s',params={'wd':'Python'}) print(r.request.url) #http://www.baidu.com/s?wd=Python r.raise_for_status() r.encoding = r.apparent_encoding print(len(r.text)) except: print('Error') import requests try: keyword = 'Python' kv = {'q':keyword} r = requests.get('https://www.so.com/s',params=kv) print(r.request.url) #https://www.so.com/s?q=Python r.raise_for_status() r.encoding = r.apparent_encoding print(len(r.text)) except: print('error')
#作业5查ip归属 import requests url = 'http://www.ip138.com/ips138.asp?ip=' try: r = requests.get(url + '114.116.113.46') r.raise_for_status() r.encoding = r.apparent_encoding print(r.text) except: print('error')
#4爬取保存图片 import requests import os url = 'http://p1.so.qhimgs1.com/bdr/326__/t01d9dff613f7d05381.jpg' root = 'D://pics//' path = root + os.path.basename(url) #os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素 #path = root + url.split('/')[-1] try: if not os.path.exists(root): #os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False os.mkdir(root) if not os.path.exists(path): r = requests.get(url) r.raise_for_status() r.encoding = r.apparent_encoding with open(path,'wb') as f: f.write(r.content) print('文件保存成功') else: print('文件存在') except: print('爬取失败')