问题:
书接上文,有些网站是不同意程序直接用之前的方式访问的,如果我们传入的参数不合适,站点就不会响应,所以我们需要对Request进行进一步的伪装。
Headers
以Bilibili的登录为例,我使用的是Ubuntu自带的Firefox浏览器,在登录页面,右键点击查看元素后,点击第一个GET,点击原始头,如图:
agent
我们可以在请求头中看到User-Agent,referer等信息,agent是请求的身份,如果没有写入请求身份,服务器可能不会响应,所以对程序进行更改:
import urllib
import urllib2
url = 'https://passport.bilibili.com/login'
user_agent = ' Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:54.0) Gecko/20100101 Firefox/54.0'
values = {"username":"xxxxxx","password":"xxxxxx"}
headers = {'User-Agent':user_agent}
data = urllib.urlencode(values)
url = "https://xxxxxxxx"
request = urllib2.Request(url,data)
response = urllib2.urlopen(request)
print response.read()
referer
除了识别请求的身份,服务器还会识别headers中的referer是不是它自己,这叫“反盗链”。所以我们在headers中再加入refererheaders = {'User-Agent':user_agent,'Referer':' https://passport.bilibili.com/login'}
这样就能解决反盗链的问题了。
header中需要注意的一些属性
- User-Agent:有些服务器或Proxy会通过该值来判断是否是浏览器发出的请求
- Content-Type:在使用REST接口时,服务器会检查该值,用来确定HTTP Body中的内容如何解析
- application/xml:在XML RPC,如RESTful/SOAP调用时使用
- application/jison:在JSON RPC调用时使用
- application/x-www-form-urlencoded:浏览器提交web表单时使用
在使用服务器提供的RESTful或SOAP服务时,Content-Type设置错误会导致服务器拒绝服务
其他有必要的可以审查浏览器的headers内容,构建request时写入相同的数据就行了。
Proxy(代理)
urllib2默认使用环境变量http_proxy来设置HTTP Proxy。但是假如一个网站会检测某一段时间某个IP的访问次数,并且对访问次数作出限制,就会禁止访问,所以我们需要定时更换代理进行访问
import urllib2
enable_proxy = True #代理是否作用
proxy_handler = urllib2.ProxyHandler({"http":'127.0.0.1:8087'}) #用ProxyHandler类设置本机8087端口为代理
null_proxy_handler = urllib2.ProxyHandler({})
if enable_proxy:
opener = urllib2.build_opener(proxy_handler) #设置新的opener
else:
opener = urllib2.build_opener(null_proxy_handler)
urllib2.install_opener(opener) #设置urllib2的全局opener,正常情况下我们使用的是默认opener,即urlopen,通常用opener对象的open方法,而不是调用install_opener
openers和handlers
openners使用处理器handlers,handlers处理背后的工作,如:通过特定协议打开URL,处理URL打开时的各个方面,比如HTTP重定向或者HTTP cookies。
Timeout
timeout是urlopen方法的第三个参数,设置访问等待时间,在传参时,data和timeout都是由默认值的,要注意不传data时,要特别指定timeout=?
import urllib2
response = urllib2.urlopen('http://www.baidu.com',timeout=10) #未传入data
#response = urllib2.urlopen('http://www.baidu.com',data,10) 传入data
总结:
关于urllib2更详细的一些使用细节