Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库。它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTTP 测试需求。
pip install requests
easy_install requests
requests为爬虫开发者们提供了8种基本的请求方式,由于在web开发过程中,大家发现对于服务器数据的处理方式没有一开始制定标准时设计的那么复杂,所以一般情况下都简化成了get/post两种常见的请求方式
req = requests.request(method,url, **kw)
req = requests.post(url, **kw)
req = requests.get(url, **kw)
req = requests.delete(url, **kw)
req = requests.put(url, **kw)
req = requests.head(url, **kw)
req = requests.options(url, **kw)
req = requests.patch(url, **kw)
#python开发人员常用的测试地址 http://httpbin.org/gets
r = requests.get("http://httpbin.org/get")
import requests payload = {'key1': 'value1', 'key2': 'value2'} r = requests.get("http://httpbin.org/get", params=payload) print r.url 运行结果: http://httpbin.org/get?key2=value2&key1=value1
写一个JSON文件命名为a.json ["foo", "bar", { "foo": "bar" }] 利用如下程序请求并解析 import requests r = requests.get("a.json") print r.text print r.json() 运行结果如下,其中一个是直接输出内容,另外一个方法是利用 json() >方法解析 ["foo", "bar", { "foo": "bar" }] [u'foo', u'bar', {u'foo': u'bar'}]
r = requests.get('https://github.com/timeline.json', stream=True) r.raw <requests.packages.urllib3.response.HTTPResponse object at >0x101194810> r.raw.read(10) '\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03' 这样就获取了网页原始套接字内容。
import requests payload = {'key1': 'value1', 'key2': 'value2'} headers = {'content-type': 'application/json'} r = requests.get("http://httpbin.org/get", params=payload, headers=headers) print r.url
import requests payload = {'key1': 'value1', 'key2': 'value2'} r = requests.post("http://httpbin.org/post", data=payload) print r.text 运行结果: { "args": {}, "data": "", "files": {}, "form": { "key1": "value1", "key2": "value2" }, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Content-Length": "23", "Content-Type": "application/x-www-form-urlencoded", "Host": "httpbin.org", "User-Agent": "python-requests/2.9.1" }, "json": null, "url": "http://httpbin.org/post" }
import json import requests url = 'http://httpbin.org/post' payload = {'some': 'data'} r = requests.post(url, data=json.dumps(payload)) print r.text 运行结果: { "args": {}, "data": "{\"some\": \"data\"}", "files": {}, "form": {}, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Content-Length": "16", "Host": "httpbin.org", "User-Agent": "python-requests/2.9.1" }, "json": { "some": "data" }, "url": "http://httpbin.org/post" } 通过上述方法,我们可以POST JSON格式的数据
新建一个 a.txt 的文件,内容写上 Hello World! import requests url = 'http://httpbin.org/post' files = {'file': open('test.txt', 'rb')} r = requests.post(url, files=files) print r.text 运行结果: { "args": {}, "data": "", "files": { "file": "Hello World!" }, "form": {}, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Content-Length": "156", "Content-Type": "multipart/form-data; >boundary=7d8eb5ff99a04c11bb3e862ce78d7000", "Host": "httpbin.org", "User-Agent": "python-requests/2.9.1" }, "json": null, "url": "http://httpbin.org/post" } 这样我们便成功完成了一个文件的上传。
with open('massive-body') as f: response = requests.post('http://some.url/streamed', data=f) print(response.text)
import requests response = requests.get("http://www.baidu.com/") # 返回CookieJar对象: cookiejar = response.cookies #将CookieJar转为字典: cookiedict = requests.utils.dict_from_cookiejar(cookiejar) print cookiejar print cookiedict
requests.get('http://github.com', timeout=0.001) 注:timeout 仅对连接过程有效,与响应体的下载无关。
在以上的请求中,每次请求其实都相当于发起了一个新的请求。也就是相当于我们每个请求都用了不同的浏览器单独打开的效果。也就是它并不是指的一个会话,即使请求的是同一个网址。比如
import requests requests.get('http://httpbin.org/cookies/set/sessioncookie/123456789') r = requests.get("http://httpbin.org/cookies") print(r.text) 结果: { "cookies": {} }
import requests s = requests.Session() s.get('http://httpbin.org/cookies/set/sessioncookie/123456789') r = s.get("http://httpbin.org/cookies") print(r.text) 在这里我们请求了两次,一次是设置 cookies,一次是获得 cookies 运行结果 { "cookies": { "sessioncookie": "123456789" } }
import requests s = requests.Session() s.headers.update({'x-test': 'true'}) r = s.get('http://httpbin.org/headers', headers={'x-test2': 'true'}) print r.text 通过 s.headers.update 方法设置了 headers 的变量。两个变量都传送过>去了。 运行结果: { "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Host": "httpbin.org", "User-Agent": "python-requests/2.9.1", "X-Test": "true", "X-Test2": "true" } }
{ "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Host": "httpbin.org", "User-Agent": "python-requests/2.9.1", "X-Test": "true" } }
r = s.get('http://httpbin.org/headers', headers={'x-test': None}) 运行结果: { "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Host": "httpbin.org", "User-Agent": "python-requests/2.9.1" } }
现在随处可见 https 开头的网站,Requests可以为HTTPS请求验证SSL证书,就像web浏览器一样。要想检查某个主机的SSL证书,你可以使用 verify 参数,比如12306的证书无效。
测试如下: import requests r = requests.get('https://kyfw.12306.cn/otn/', verify=True) print r.text 结果: requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)
测试12306的证书无效
import requests r = requests.get('https://kyfw.12306.cn/otn/', verify=False) print r.text 在默认情况下 verify 是 True,所以如果需要的话,需要手动设置下这个变量。
源码中我们可以看到默认verify=False
# 1. 导入Python SSL处理模块
import ssl
# 2. 表示忽略未经核实的SSL证书认证
context = ssl._create_unverified_context()
import requests # 根据协议类型,选择不同的代理 proxies = { "https": "http://41.118.132.69:4433" "http": "http://41.118.132.69:4433" } r = requests.post("http://httpbin.org/post", proxies=proxies) print r.text
#私密代理
import requests
# 如果代理需要使用HTTP Basic Auth,可以使用下面这种格式:
proxy = { "http": "mr_mao_hacker:sffqry9r@61.158.163.130:16816" }
response = requests.get("http://www.baidu.com", proxies = proxy)
print response.text
import requests
auth=('test', '123456')
response = requests.get('http://192.168.199.107', auth = auth)
print response.text
export HTTP_PROXY="http://10.10.1.10:3128" export HTTPS_PROXY="http://10.10.1.10:1080" 通过以上方式,可以方便地设置代理。
安装好request模块之后,在程序中就可以通过import引入并且使用了
# -*- coding:utf-8 -*-
# 引入requests模块
import requests
# 发送请求,得到服务器返回的响应对象,通过encoding设置响应中数据的编码
response = requests.get("http://www.sojson.com/open/api/weather/json.shtml?city=%E9%83%91%E5%B7%9E")
response.encoding="utf-8"
# 通过text打印响应中的文本数据
print(response.text)
结果:
{"message":"Success !",
"status":200,"city":"郑州","count":26,
"data":{"shidu":"74%","pm25":71.0,"pm10":145.0,"quality":"良","wendu":"31",
"ganmao":"极少数敏感人群应减少户外活动",
"yesterday":{"date":"10日星期四","sunrise":"05:41","high":"高温 37.0℃",
"low":"低温 25.0℃","sunset":"19:20","aqi":141.0,"fx":"西风","fl":"<3
级","type":"晴","notice":"lovely sunshine,尽情享受阳光的温暖吧"},
"forecast":[{"date":"11日星期五","sunrise":"05:42","high":"高温 37.0℃",
"low":"低温 25.0℃","sunset":"19:19","aqi":100.0,"fx":"南风",
"fl":"<3级","type":"晴","notice":"天气干燥,请适当增加室内湿度"},
{"date":"12日星期六","sunrise":"05:42","high":"高温 31.0℃","low":"低温
24.0℃","sunset":"19:18","aqi":55.0,"fx":"东风","fl":"<3级","type":"阵雨",
"notice":"突如其来的雨,总叫让人措手不及"},{"date":"13日星期日",
"sunrise":"05:43","high":"高温 30.0℃","low":"低温 24.0℃",
"sunset":"19:17","aqi":60.0,"fx":"北风","fl":"<3级","type":"阵雨","notice":"突如其来的雨,总叫让人措手不及"},
{"date":"14日星期一","sunrise":"05:44","high":"高温 33.0℃",
"low":"低温 24.0℃","sunset":"19:16","aqi":62.0,"fx":"东北风","fl":"<3级",
"type":"晴","notice":"lovely sunshine,尽情享受阳光的温暖吧"},
{"date":"15日星期二","sunrise":"05:45","high":"高温 35.0℃",
"low":"低温 24.0℃","sunset":"19:14","aqi":65.0,"fx":"南风","fl":"<3级",
"type":"晴","notice":"天气干燥,请适当增加室内湿度"}]}}
先获取图片链接地址
# -*- coding:utf-8 -*-
import requests,re,urllib,urllib2
#定义引擎函数模块
def getImg(url):
content = load_url(url)
#数据获取完成,定义正则表达式,筛选数据
reg = re.compile('"thumbURL":\s*"(.*?)"', re.S)
data_list = data_filter(content,reg)
#保存数据
for index,data_url in enumerate(data_list):
sava_data(data_url,"./images/" + str(index) + ".jpg")
#定义爬取数据的函数
def load_url(url):
"""
作用:爬取指定url地址中的数据
:param url: 指定的url地址
:return: 所有爬取到的数据
"""
print('开始爬取图片')
my_headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36',
}
response = requests.get(url,headers=my_headers,verify=False)
response.encoding = 'UTF-8'
content = response.text
print('数据爬取完成')
return content
#定义筛选数据的函数
def data_filter(data,reg):
"""
作用:进行数据按照指定描述的正则筛选
:param data: 所有数据
:param reg: 正则表达式
:return: 返回筛选到的数据列表
"""
print('---开始筛选数据')
data_list = reg.findall(data)
print('筛选数据完成')
return data_list
#定义保存数据的函数
def sava_data(url_content,file_name):
"""
作用:保存数据
:param url_content:需要保存的数据
:param file_name: 文件名称
:return:
"""
print('开始保存数据')
try:
urllib.urlretrieve(url_content, file_name)
#另外一种保存方式
# my_headers = {
# 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36',
# }
# print (url_content)
# content = requests.get(url_content, headers=my_headers).content
# with open(file_name, "wb") as f:
# f.write(content)
print('图片下载成功')
except Exception as result:
print('图片下载失败'+str(result))
print('数据保存完成')
#定义主程序入口
if __name__ == '__main__':
#定义获取各种需要的参数数据
url = 'https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord=%E4%BD%A0%E7%9A%84%E5%90%8D%E5%AD%97&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&word=%E4%BD%A0%E7%9A%84%E5%90%8D%E5%AD%97&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&pn=30&rn=30&gsm=1e&1502454817018='
#调用引擎对象,执行爬虫
getImg(url)
结果:
你的名字
写到最后说些题外话,今天爬取一个网站的时候还发生了一件好玩的事,网站的反爬机制导致爬取的数据只是一个html网页,看到了页面上的话,我想起了一句话,对于爬虫工程师来说每天都是不停地和对方的反爬工程师斗智斗勇。
那么问题来了,到底什么是世界上最牛逼的语言
Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据。官方解释如下:
Beautiful Soup 3 目前已经停止开发,推荐在现在的项目中使用Beautiful Soup 4,不过它已经被移植到BS4了,也就是说导入时我们需要 import bs4 。所以这里我们用的版本是 Beautiful Soup 4.3.2 (简称BS4),另外据说 BS4 对 Python3 的支持不够好,不过我用的是 Python2.7.7,如果有小伙伴用的是 Python3 版本,可以考虑下载 BS3 版本。
easy_install beautifulsoup4
pip install beautifulsoup4
由于我的是python2和python3共存,所以安装时需加上python版本安装
easy_install html5lib
pip install html5lib
Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,如果我们不安装它,则 Python 会使用 Python默认的解析器,lxml 解析器更加强大,速度更快,推荐安装。
解析器 | 使用方法 | 优势 | 劣势 |
---|---|---|---|
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格式的文档 | 速度慢不依赖外部扩展 |
find_all( name , attrs , recursive , string , **kwargs )
find_all()
几乎是 Beautiful Soup中最常用的搜索方法,也可以使用其简写方法,以下代码等价:soup.find_all("a")
soup("a")
get_text()
方法,这个方法获取到 tag 中包含的所有文版内容包括子孙 tag 中的内容,并将结果作为 Unicode 字符串返回:tag.p.a.get_text()
参考文档:Requests官方文档及崔庆才老师的个人博客、 Beautiful Soup 4.4.0 文档 (中文文档)