1.urllib.urlencode()
urllib 和 urllib2区别:
- urllib 仅可以接受URL,不能创建 设置了headers 的Request 类实例;
- urllib 提供 urlencode 方法用来GET查询字符串的产生,而 urllib2 则没有。(这是 urllib 和 urllib2 经常一起使用的主要原因)
- 编码工作使用urllib的urlencode()函数,帮我们将key:value这样的键值对转换成"key=value"这样的字符串,解码工作可以使用urllib的unquote()函数。
#urllib.urlencode()编码转换
import urllib.request as urllib2
import urllib
word = {"wd":'天上人间'}
#通过urllib.parse.urlencode()方法,将字典键值对按URL编码转换,从而能被web服务器接受。
word = urllib.parse.urlencode(word)
print(word)
#通过urllib.parse.unquote()方法,把 URL编码字符串,转换回原先字符串。
word = urllib.parse.unquote(word)
print(word)
当HTTP请求提交数据,需要编码成 URL编码格式,然后做为url的一部分。
2.Get方式
GET请求一般用于我们向服务器获取数据
#Get方法
import urllib.request as urllib2
import urllib
url = 'http://www.baidu.com/s'
word = {'wd':'天上人间'}
word = urllib.parse.urlencode(word)
url = url + '?' +word
print(url)
header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0'}
request = urllib2.Request(url,headers = header)
response = urllib2.urlopen(request)
html = response.read().decode(encoding='utf-8')
print(html)
with open('Get方法.html','w',encoding='utf-8') as f:
f.write(html)
3.实例:批量爬取贴吧页面数据
百度贴吧LOL吧
第一页:http://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=0
第二页: http://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=50
第三页: http://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=100
贴吧中每个页面不同之处,就是url最后的pn的值,其余的都是一样的,我们可以抓住这个规律。
#爬取百度贴吧
import urllib.request as urllib2
import urllib
def main():
kw = input('请输入要爬取的贴吧:')
startPage = int(input('请输入要爬取的起始页:'))
endPage = int(input('请输入要爬取的终止页:'))
url = 'http://tieba.baidu.com/f?'
key = urllib.parse.urlencode({'kw':kw})
url = url + key
tiebaSpider(url,startPage,endPage)
def tiebaSpider(url,startPage,endPage):
for page in range(startPage,endPage+1):
pn = (page-1)*50
filename = '第' + str(page) +'页.html'
fullurl = url + '&pn' + str(pn)
print(fullurl)
html = loadPage(fullurl,filename)
writeFile(html,filename)
def loadPage(fullurl,filename):
print('正在下载' + filename)
header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0'}
request = urllib2.Request(fullurl,headers = header)
response = urllib2.urlopen(request)
return response.read().decode(encoding = 'utf-8')
def writeFile(html,filename):
print('正在储存' + filename)
with open(filename,'w',encoding='utf-8') as f:
f.write(html)
print('*'*10)
if __name__ == '__main__':
main()
4.POST方式
Request请求对象的里有data参数,它就是用在POST里的,我们要传送的数据就是这个参数data,data是一个字典,里面要匹配键值对。
抓包得到的数据(以有道翻译为例)
POST http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule HTTP/1.1
Host: fanyi.youdao.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 240
Connection: keep-alive
Referer: http://fanyi.youdao.com/
Cookie: YOUDAO_MOBILE_ACCESS_TYPE=1; OUTFOX_SEARCH_USER_ID=552861304@10.169.0.83; JSESSIONID=aaax4O7FEUFXz_pXuDhVw; ___rl__test__cookies=1562850476933; OUTFOX_SEARCH_USER_ID_NCOO=2083779513.5129535
i=good%0A&from=AUTO&to=AUTO&smartresult=dict&client=fanyideskweb&salt=15628504769404&sign=76f8ee72e5d78009e6b10230946cf2b6&ts=1562850476940&bv=e2a78ed30c66e16a857c5b6486a1d326&doctype=json&version=2.1&keyfrom=fanyi.web&action=FY_BY_REALTlME
请求代码如下
#Post方法
import urllib.request as urllib2
import urllib
import json
#抓包得到url
url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
#基于有道的反爬虫机制,去掉_o才能正常爬虫访问
url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule'
#模拟浏览器身份
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0'}
#post发送的数据包,字典形式
formdata = {
'i':'good',
'from':'AUTO',
'to':'AUTO',
'smartresult':'dict',
'client':'fanyideskweb',
'salt':'15628504769404',
'sign':'76f8ee72e5d78009e6b10230946cf2b6',
'doctype':'json',
'keyfrom':'fanyi.web',
'ue':'utf-8',
'action':'FY_BY_ENTER',
}
#对数据包进行转码,不转码将出现TypeError
data = urllib.parse.urlencode(formdata).encode(encoding = "utf-8")
#创建request实例化对象
request = urllib2.Request(url,data = data,headers = headers)
#对目标url进行访问
response = urllib2.urlopen(request)
#得到服务器响应内容并进行转码
html = response.read().decode(encoding='utf-8')
#打印返回的内容
print(html)
#对返回的json格式的内容进行解码
html = json.loads(html)
#定位json中需要的内容部分并打印出来
print('翻译结果:%s'%(html['translateResult'][0][0]['tgt']))
关于怎样在不删除有道url中的_o使用爬虫访问,请访问:
https://blog.youkuaiyun.com/li939891142/article/details/84592442
5.HTTPS请求 SSL证书验证
现在随处可见 https 开头的网站,urllib.request可以为 HTTPS 请求验证SSL证书,就像web浏览器一样,如果网站的SSL证书是经过CA认证的,才能够正常访问。如果SSL证书验证不通过,或者操作系统不信任服务器的安全证书会警告用户证书不受信任。
使用urllib.request在访问的时候则会报出SSLError:当遇到这种网站,我们需要单独处理SSL证书,让程序忽略SSL证书验证错误,才可正常访问。
import urllib.request as urllib2
import urllib
# 导入SSL处理模块
import ssl
# 表示忽略未经认证的SSL证书认证
context = ssl._create_unverified_context()
url = 'http://www.12306.cn/mormhweb/'
headers = headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0'}
request = urllib2.Request(url,headers = headers)
#在urlopen()方法里面指明添加context参数
response = urllib2.urlopen(request,context = context)
html = response.read().decode(encoding = 'utf-8')
print(html)