Python中第三方库Requests库的用法

 python  Python中第三方库Requests库的用法已关闭评论
10月 092017
 

python中第三方库Requests库的使用,来自:http://www.jb51.net/article/108168.htm

一、Requests库的安装

利用 pip 安装,如果你安装了pip包(一款Python包管理工具,不知道可以百度哟),或者集成环境,比如Python(x,y)或者anaconda的话,就可以直接使用pip安装Python的库。

$ pip install requests

安装完成之后,下面来看一下基本的方法:

#get请求方法
 >>> r = requests.get('https://api.github.com/user', auth=('user', 'pass'))
#打印get请求的状态码
 >>> r.status_code
200
#查看请求的数据类型,可以看到是json格式,utf-8编码
 >>> r.headers['content-type']
'application/json; charset=utf8'
 >>> r.encoding
'utf-8'
#打印请求到的内容
 >>> r.text
u'{"type":"User"...'
#输出json格式数据
 >>> r.json()
 {u'private_gists': 419, u'total_private_repos': 77, ...}

下面看一个小栗子:

#小例子
import requests

r = requests.get('http://www.baidu.com')
print type(r)
print r.status_code
print r.encoding
print r.text
print r.cookies
'''请求了百度的网址,然后打印出了返回结果的类型,状态码,编码方式,Cookies等内容 输出:'''
<class 'requests.models.Response'>
200
UTF-8
<RequestsCookieJar[]>

二、http基本请求

requests库提供了http所有的基本请求方式。例如:

r = requests.post("http://httpbin.org/post")
r = requests.put("http://httpbin.org/put")
r = requests.delete("http://httpbin.org/delete")
r = requests.head("http://httpbin.org/get")
r = requests.options(http://httpbin.org/get)

基本GET请求

r = requests.get("http://httpbin.org/get")
#如果想要加参数,可以利用 params 参数:
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文件,可以利用 json() 方法解析,例如自己写一个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.raw 。 不过需要在初始请求中设置 stream=True。

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'

这样就获取了网页原始套接字内容。

如果想添加 headers,可以传 headers 参数:

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
#通过headers参数可以增加请求头中的headers信息

三、基本POST请求

对于 POST 请求来说,我们一般需要为它增加一些参数。那么最基本的传参方法可以利用 data 这个参数。

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": "http://httpbin.org", 
"User-Agent": "python-requests/2.9.1"
}, 
"json": null, 
"url": "http://httpbin.org/post"
}

可以看到参数传成功了,然后服务器返回了我们传的数据。

有时候我们需要传送的信息不是表单形式的,需要我们传JSON格式的数据过去,所以我们可以用 json.dumps() 方法把表单数据序列化。

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": "http://httpbin.org", 
"User-Agent": "python-requests/2.9.1"
}, 
"json": {
"some": "data"
}, 
"url": "http://httpbin.org/post"
}

通过上述方法,我们可以POST JSON格式的数据

如果想要上传文件,那么直接用 file 参数即可:

#新建一个 test.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": "http://httpbin.org", 
"User-Agent": "python-requests/2.9.1"
}, 
"json": null, 
"url": "http://httpbin.org/post"
}

这样我们便成功完成了一个文件的上传。

requests 是支持流式上传的,这允许你发送大的数据流或文件而无需先把它们读入内存。要使用流式上传,仅需为你的请求体提供一个类文件对象即可,非常方便:

with open('massive-body') as f:
requests.post('http://some.url/streamed', data=f)

四、Cookies

如果一个响应中包含了cookie,那么我们可以利用 cookies 变量来拿到:

import requests

url = 'Example Domain'
r = requests.get(url)
print r.cookies
print r.cookies['example_cookie_name']

以上程序仅是样例,可以用 cookies 变量来得到站点的 cookies

另外可以利用 cookies 变量来向服务器发送 cookies 信息:

import requests

url = 'http://httpbin.org/cookies'
cookies = dict(cookies_are='working')
r = requests.get(url, cookies=cookies)
print r.text
#输出:
'{"cookies": {"cookies_are": "working"}}'

五、超时配置

可以利用 timeout 变量来配置最大请求时间

requests.get(‘Build software better, together', timeout=0.001)

注:timeout 仅对连接过程有效,与响应体的下载无关。

也就是说,这个时间只限制请求的时间。即使返回的 response 包含很大内容,下载需要一定时间。

六、会话对象

在以上的请求中,每次请求其实都相当于发起了一个新的请求。也就是相当于我们每个请求都用了不同的浏览器单独打开的效果。也就是它并不是指的一个会话,即使请求的是同一个网址。比如:

import requests

requests.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
r = requests.get("http://httpbin.org/cookies")
print(r.text)
#结果是:
{
"cookies": {}
}

很明显,这不在一个会话中,无法获取 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"
}
}

发现可以成功获取到 cookies 了,这就是建立一个会话到作用。

那么既然会话是一个全局的变量,那么我们肯定可以用来全局的配置了。

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,那么会出现什么结果?很简单,两个变量都传送过去了。 运行结果:'''
{
"headers": {
"Accept": "*/*", 
"Accept-Encoding": "gzip, deflate", 
"Host": "http://httpbin.org", 
"User-Agent": "python-requests/2.9.1", 
"X-Test": "true", 
"X-Test2": "true"
}
}

如果get方法传的headers 同样也是 x-test 呢?

r = s.get('http://httpbin.org/headers', headers={'x-test': 'true'})

#它会覆盖掉全局的配置:
{
"headers": {
"Accept": "*/*", 
"Accept-Encoding": "gzip, deflate", 
"Host": "http://httpbin.org", 
"User-Agent": "python-requests/2.9.1", 
"X-Test": "true"
}
}

如果不想要全局配置中的一个变量了呢?很简单,设置为 None 即可。

r = s.get('http://httpbin.org/headers', headers={'x-test': None})
{
"headers": {
"Accept": "*/*", 
"Accept-Encoding": "gzip, deflate", 
"Host": "http://httpbin.org", 
"User-Agent": "python-requests/2.9.1"
}
}

以上就是 session 会话的基本用法。

七、SSL证书验证

现在随处可见 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)

来试下 github 的:

import requests

r = requests.get('Build software better, together', verify=True)
print r.text

嗯,正常请求,由于内容太多,我就不粘贴输出了。

如果我们想跳过刚才 12306 的证书验证,把 verify 设置为 False 即可:

import requests

r = requests.get('https://kyfw.12306.cn/otn/', verify=False)
print r.text

发现就可以正常请求了。在默认情况下 verify 是 True,所以如果需要的话,需要手动设置下这个变量。

八、代理

如果需要使用代理,你可以通过为任意请求方法提供 proxies 参数来配置单个请求。

import requests

proxies = {
"https": "http://41.118.132.69:4433"
}
r = requests.post("http://httpbin.org/post", proxies=proxies)
print r.text
#也可以通过环境变量 HTTP_PROXY 和 HTTPS_PROXY 来配置代理
export HTTP_PROXY="http://10.10.1.10:3128"
	

export HTTPS_PROXY=http://10.10.1.10:1080


Xpath语法及python 中lxml库的用法

 python  Xpath语法及python 中lxml库的用法已关闭评论
10月 242016
 

参考来源

lxml用法源自 lxml python 官方文档,更多内容请直接参阅官方文档,本文对其进行翻译与整理。

lxml

XPath语法参考 w3school

w3school

安装

利用 pip 安装即可

XPath语法

XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。XPath 是 W3C XSLT 标准的主要元素,并且 XQuery 和 XPointer 都构建于 XPath 表达之上。

节点关系

(1)父(Parent)

每个元素以及属性都有一个父。

在下面的例子中,book 元素是 title、author、year 以及 price 元素的父:

(2)子(Children)

元素节点可有零个、一个或多个子。

在下面的例子中,title、author、year 以及 price 元素都是 book 元素的子:

(3)同胞(Sibling)

拥有相同的父的节点

在下面的例子中,title、author、year 以及 price 元素都是同胞:

(4)先辈(Ancestor)

某节点的父、父的父,等等。

在下面的例子中,title 元素的先辈是 book 元素和 bookstore 元素:

(5)后代(Descendant)

某个节点的子,子的子,等等。

在下面的例子中,bookstore 的后代是 book、title、author、year 以及 price 元素:

选取节点

XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。

下面列出了最有用的路径表达式:

表达式 描述
nodename 选取此节点的所有子节点。
/ 从根节点选取。
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
. 选取当前节点。
.. 选取当前节点的父节点。
@ 选取属性。

实例

在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:

路径表达式 结果
bookstore 选取 bookstore 元素的所有子节点。
/bookstore 选取根元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!
bookstore/book 选取属于 bookstore 的子元素的所有 book 元素。
//book 选取所有 book 子元素,而不管它们在文档中的位置。
bookstore//book 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。
//@lang 选取名为 lang 的所有属性。

谓语(Predicates)

谓语用来查找某个特定的节点或者包含某个指定的值的节点。

谓语被嵌在方括号中。

实例

在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:

路径表达式 结果
/bookstore/book[1] 选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()] 选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1] 选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()<3] 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
//title[@lang] 选取所有拥有名为 lang 的属性的 title 元素。
//title[@lang=’eng’] 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。
/bookstore/book[price>35.00] 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。
/bookstore/book[price>35.00]/title 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。

选取未知节点

XPath 通配符可用来选取未知的 XML 元素。

通配符 描述
* 匹配任何元素节点。
@* 匹配任何属性节点。
node() 匹配任何类型的节点。

实例

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

路径表达式 结果
/bookstore/* 选取 bookstore 元素的所有子元素。
//* 选取文档中的所有元素。
//title[@*] 选取所有带有属性的 title 元素。

选取若干路径

通过在路径表达式中使用“|”运算符,您可以选取若干个路径。

实例

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

路径表达式 结果
//book/title | //book/price 选取 book 元素的所有 title 和 price 元素。
//title | //price 选取文档中的所有 title 和 price 元素。
/bookstore/book/title | //price 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。

XPath 运算符

下面列出了可用在 XPath 表达式中的运算符:

运算符 描述 实例 返回值
| 计算两个节点集 //book | //cd 返回所有拥有 book 和 cd 元素的节点集
+ 加法 6 + 4 10
减法 6 – 4 2
* 乘法 6 * 4 24
div 除法 8 div 4 2
= 等于 price=9.80 如果 price 是 9.80,则返回 true。如果 price 是 9.90,则返回 false。
!= 不等于 price!=9.80 如果 price 是 9.90,则返回 true。如果 price 是 9.80,则返回 false。
< 小于 price<9.80 如果 price 是 9.00,则返回 true。如果 price 是 9.90,则返回 false。
<= 小于或等于 price<=9.80 如果 price 是 9.00,则返回 true。如果 price 是 9.90,则返回 false。
> 大于 price>9.80 如果 price 是 9.90,则返回 true。如果 price 是 9.80,则返回 false。
>= 大于或等于 price>=9.80 如果 price 是 9.90,则返回 true。如果 price 是 9.70,则返回 false。
or price=9.80 or price=9.70 如果 price 是 9.80,则返回 true。如果 price 是 9.50,则返回 false。
and price>9.00 and price<9.90 如果 price 是 9.80,则返回 true。如果 price 是 8.50,则返回 false。
mod 计算除法的余数 5 mod 2 1

lxml用法

初步使用

首先我们利用它来解析 HTML 代码,先来一个小例子来感受一下它的基本用法。

首先我们使用 lxml 的 etree 库,然后利用 etree.HTML 初始化,然后我们将其打印出来。

其中,这里体现了 lxml 的一个非常实用的功能就是自动修正 html 代码,大家应该注意到了,最后一个 li 标签,其实我把尾标签删掉了,是不闭合的。不过,lxml 因为继承了 libxml2 的特性,具有自动修正 HTML 代码的功能。

所以输出结果是这样的

不仅补全了 li 标签,还添加了 body,html 标签。

文件读取

除了直接读取字符串,还支持从文件读取内容。比如我们新建一个文件叫做 hello.html,内容为

利用 parse 方法来读取文件。

同样可以得到相同的结果。

XPath实例测试

依然以上一段程序为例

(1)获取所有的 <li> 标签

运行结果

可见,etree.parse 的类型是 ElementTree,通过调用 xpath 以后,得到了一个列表,包含了 5 个 <li> 元素,每个元素都是 Element 类型

(2)获取 <li> 标签的所有 class

运行结果

(3)获取 <li> 标签下 href 为 link1.html 的 <a> 标签

运行结果

(4)获取 <li> 标签下的所有 <span> 标签

注意这么写是不对的

因为 / 是用来获取子元素的,而 <span> 并不是 <li> 的子元素,所以,要用双斜杠

运行结果

(5)获取 <li> 标签下的所有 class,不包括 <li>

运行结果

(6)获取最后一个 <li> 的 <a> 的 href

运行结果

(7)获取倒数第二个元素的内容

运行结果

(8)获取 class 为 bold 的标签名

运行结果

通过以上实例的练习,相信大家对 XPath 的基本用法有了基本的了解。也可以利用 text 方法来获取元素的内容。

大家多加练习!

结语

XPath 是一个非常好用的解析方法,同时也作为爬虫学习的基础,在后面的 selenium 以及 scrapy 框架中都会涉及到这部分知识,希望大家可以把它的语法掌握清楚,为后面的深入研究做好铺垫。

转自:https://cuiqingcai.com/2621.html

python中format函数的用法

 python  python中format函数的用法已关闭评论
8月 022016
 

越來越喜欢python了,这个python的format函数使用的好真可以简便不少

自python2.6开始,新增了一种格式化字符串的函数str.format(),可谓威力十足。那么,他跟之前的%型格式化字符串相比,有什么优越的存在呢?让我们来揭开它羞答答的面纱。
语法

它通过{}和:来代替%。
“映射”示例

通过位置

1
2
3
4
5
6
In [1]:'{0},{1}’.format(‘kzc’,18)
Out[1]:’kzc,18′
In [2]:'{},{}’.format(‘kzc’,18)
Out[2]:’kzc,18′
In [3]:'{1},{0},{1}’.format(‘kzc’,18)
Out[3]:’18,kzc,18′

字符串的format函数可以接受不限个参数,位置可以不按顺序,可以不用或者用多次,不过2.6不能为空{},2.7才可以。
通过关键字参数

?
1
2
In [5]:'{name},{age}’.format(age=18,name=’kzc’)
Out[5]:’kzc,18′

通过对象属性

?
1
2
3
4
5
classPerson:
  def__init__(self,name,age):
    self.name,self.age=name,age
    def__str__(self):
      return’This guy is {self.name},is {self.age} old’.format(self=self)

?
1
2
In [2]:str(Person(‘kzc’,18))
Out[2]:’This guy is kzc,is 18 old’

通过下标

?
1
2
3
In [7]: p=[‘kzc’,18]
In [8]:'{0[0]},{0[1]}’.format(p)
Out[8]:’kzc,18′

有了这些便捷的“映射”方式,我们就有了偷懒利器。基本的python知识告诉我们,list和tuple可以通过“打散”成普通参数给函数,而dict可以打散成关键字参数给函数(通过和*)。所以可以轻松的传个list/tuple/dict给format函数。非常灵活。
格式限定符

它有着丰富的的“格式限定符”(语法是{}中带:号),比如:

填充与对齐
填充常跟对齐一起使用
^、<、>分别是居中、左对齐、右对齐,后面带宽度
:号后面带填充的字符,只能是一个字符,不指定的话默认是用空格填充
比如

?
1
2
3
4
5
6
In [15]:'{:>8}’.format(‘189’)
Out[15]:’   189′
In [16]:'{:0>8}’.format(‘189’)
Out[16]:’00000189′
In [17]:'{:a>8}’.format(‘189’)
Out[17]:’aaaaa189′

精度与类型f
精度常跟类型f一起使用

?
1
2
In [44]:'{:.2f}’.format(321.33345)
Out[44]:’321.33′

其中.2表示长度为2的精度,f表示float类型。

其他类型
主要就是进制了,b、d、o、x分别是二进制、十进制、八进制、十六进制。

?
1
2
3
4
5
6
7
8
In [54]:'{:b}’.format(17)
Out[54]:’10001′
In [55]:'{:d}’.format(17)
Out[55]:’17’
In [56]:'{:o}’.format(17)
Out[56]:’21’
In [57]:'{:x}’.format(17)
Out[57]:’11’

用,号还能用来做金额的千位分隔符。

?
        1
2
In [47]:'{:,}’.format(1234567890)
Out[47]:’1,234,567,890′

转自:http://www.jb51.net/article/63672.htm

git submodule用法

 git  git submodule用法已关闭评论
3月 012016
 

今天工作中碰到一个git命令 git submodule,记录下用法:


开发过程中,经常会有一些通用的部分希望抽取出来做成一个公共库来提供给别的工程来使用,而公共代码库的版本管理是个麻烦的事情。而且一旦更新了就要同步到多个引用的系统中,这个时候使用git submodule,然后执行: git submodule update就全部搞定了。

下面就以Android开发为例,讲述下submodule的具体用法。

假设一个Android Demo的目录是这样的:app, extras。其中app是程序的主要目录,extras目录是引用的一些library, 比如程序中引用了volley的library.

添加

为当前工程添加submodule,命令如下:

git submodule add 仓库地址 路径  git submodule add https://android.googlesource.com/platform/frameworks/volley extras

命令执行完成,会在当前工程根路径下生成一个名为“.gitmodules”的文件,其中记录了子模块的信息。添加完成以后,再将子模块所在的文件夹添加到工程中即可。

更新

如果过了一段时间volley库有更新,这时候我们的app也需要更新,命令如下:

git submodule update

删除

ubmodule的删除稍微麻烦点:首先,要在“.gitmodules”文件中删除相应配置信息。然后,执行“git rm –cached ”命令将子模块所在的文件从git中删除。

下载的工程带有submodule

当使用git clone下来的工程中带有submodule时,初始的时候,submodule的内容并不会自动下载下来的,此时,只需执行如下命令:

git submodule update --init --recursive

即可将子模块内容下载下来后工程才不会缺少相应的文件。

转自:http://www.stormzhang.com/git/2014/02/13/git-submodule/

10月 312014
 

记录下备用


命令行下具体用法如下: 

mysqldump -u用戶名 -p密码 -d 数据库名 表名 > 脚本名;

 

 

导出整个数据库结构和数据
mysqldump -h localhost -uroot -p123456 database > dump.sql

 

导出单个数据表结构和数据
mysqldump -h localhost -uroot -p123456  database table > dump.sql

 

 

导出整个数据库结构(不包含数据)
mysqldump -h localhost -uroot -p123456  -d database > dump.sql

 

导出单个数据表结构(不包含数据)
mysqldump -h localhost -uroot -p123456  -d database table > dump.sql