Request请求对象的里有data参数,它就是用在POST里的,我们要传送的数据就是这个参数data,data是一个字典,里面要匹配键值对。

POST请求:代码模板

导入request模块

import urllib.request

代码模板

# 首先对data进行转码,转化成str类型
data = urllib.parse.urlencode(data) 
#  post请求只支持byte类型,所以要进行再次编码
data = data.encode('utf-8')  
 # 对url和参数进行包装
new_url = urllib.request.Request(url,data) 
response = urllib.request.urlopen(new_url) 
# 读取响应结果
response = result.read() 
#  对响应结果解码
print(response.decode("utf8")) 

 

POST请求:注意事项

 

注意headers的一些属性:

 

  • Content-Length: 144: 是指发送的表单数据长度为144,也就是字符个数是144个。
  • X-Requested-With: XMLHttpRequest :表示Ajax异步请求。
  • Content-Type: application/x-www-form-urlencoded : 表示浏览器提交 Web 表单时使用,表单数据会按照 name1=value1&name2=value2 键值对形式进行编码。

 

注意User-Agent

  • 每家都有门,你以一个路人的身份直接闯进去显然不是很礼貌。同理,一些站点不喜欢被程序(非人为访问)访问,有可能会拒绝你的访问请求。
  • 但是如果我们用一个合法的身份去请求别人网站,显然人家就是欢迎的,所以我们就应该给我们的这个代码加上一个身份,就是所谓的User-Agent头。
  • 浏览器 就是互联网世界上公认被允许的身份,如果我们希望我们的爬虫程序更像一个真实用户,那我们第一步,就是需要伪装成一个被公认的浏览器。用不同的浏览器在发送请求的时候,会有不同的User-Agent头。 urllib2默认的User-Agent头为:Python-urllib/x.y(x和y是Python主版本和次版本号,例如 Python-urllib/2.7)
  • 完整的headers
# 完整的headers
headers = {
        "Accept" : "application/json, text/javascript, */*; q=0.01",
        "X-Requested-With" : "XMLHttpRequest",
        "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",
        "Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8",
    }

 

注意CA认证

  • 现在随处可见 https 开头的网站,urllib可以为 HTTPS 请求验证SSL证书,就像web浏览器一样,如果网站的SSL证书是经过CA认证的,则能够正常访问,如:https://www.baidu.com/等...
  • 如果SSL证书验证不通过,或者操作系统不信任服务器的安全证书,比如浏览器在访问12306网站如:https://www.12306.cn/mormhweb/的时候,会警告用户证书不受信任。(据说 12306 网站证书是自己做的,没有通过CA认证)

urllib:Post方式爬取AJAX加载的数据

 

  • urllib在访问的时候则会报出SSLError:
urllib2.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)>

 

所以,如果以后遇到这种网站,我们需要单独处理SSL证书,让程序忽略SSL证书验证错误,即可正常访问。

 

1.使用ssl创建未经验证的上下文,在urlopen中传入上下文参数

import ssl
import urllib2
context = ssl._create_unverified_context()
print urllib2.urlopen("https://www.12306.cn/mormhweb/", context=context).read()

2. 全局取消证书验证

import ssl
import urllib2
 
ssl._create_default_https_context = ssl._create_unverified_context
 
print urllib2.urlopen("https://www.12306.cn/mormhweb/").read()

Post方式爬取AJAX加载数据

 

   有些网页内容使用AJAX加载,只要记得,AJAX一般返回的是JSON,直接对AJAX地址进行post或get,就返回JSON数据了。

我们这里以豆瓣电影为例。

 

导入request

 

import ssl
import urllib.request
from urllib import parse

 

User-Agent头,模拟浏览器

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}

组装请求数据

url = "https://movie.douban.com/j/chart/top_list?type=11&interval_id=100%3A90&action"

formdata = {
    "start": "0",
    "limit": "20"
}

data = parse.urlencode(formdata).encode(encoding='UTF8')

获取返回结果

 

request = urllib.request.Request(url, data=data, headers=headers)

# 返回结果
response = urllib.request.urlopen(request).read()
# utf-8解码
s = response.decode('utf-8', 'ignore')
print("【返回结果】:%s" % s)

 

urllib:Post方式爬取AJAX加载的数据

 

 

完整代码Python2.7.13

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import ssl
import urllib
import urllib2

url = "https://movie.douban.com/j/chart/top_list?type=11&interval_id=100%3A90&action"

headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}

formdata = {
        "start":"0",
        "limit":"20"
    }

data = urllib.urlencode(formdata)

# 全局取消证书验证
ssl._create_default_https_context = ssl._create_unverified_context

request = urllib2.Request(url, data = data, headers = headers)

print urllib2.urlopen(request).read()

 

完整代码Python3.6.1

import ssl
import urllib.request
from urllib import parse

url = "https://movie.douban.com/j/chart/top_list?type=11&interval_id=100%3A90&action"

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}

formdata = {
    "start": "0",
    "limit": "20"
}

data = parse.urlencode(formdata).encode(encoding='UTF8')

# 全局取消证书验证
ssl._create_default_https_context = ssl._create_unverified_context

request = urllib.request.Request(url, data=data, headers=headers)

# 返回结果
response = urllib.request.urlopen(request).read()
# utf-8解码
s = response.decode('utf-8', 'ignore')
print("【返回结果】:%s" % s)

 

问题:为什么有时候POST也能在URL内看到数据?

 

  • GET方式是直接以链接形式访问,链接中包含了所有的参数,服务器端用Request.QueryString获取变量的值。如果包含了密码的话是一种不安全的选择,不过你可以直观地看到自己提交了什么内容。
  • POST则不会在网址上显示所有的参数,服务器端用Request.Form获取提交的数据,在Form提交的时候。但是HTML代码里如果不指定 method 属性,则默认为GET请求,Form中提交的数据将会附加在url之后,以?分开与url分开。
  • 表单数据可以作为 URL 字段(method="get")或者 HTTP POST (method="post")的方式来发送。比如在下面的HTML代码中,表单数据将因为 (method="get") 而附加到 URL 上:

相关文章:

  • 2021-12-17
  • 2022-12-23
  • 2022-01-20
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-05-31
  • 2021-05-10
猜你喜欢
  • 2021-10-13
  • 2021-12-12
  • 2021-12-19
  • 2021-09-05
  • 2022-12-23
  • 2022-12-23
  • 2022-01-02
相关资源
相似解决方案