爬虫第二节&Get和Post

本文介绍了urllib库在HTTP请求中的应用。阐述了urllib和urllib2的区别,以及urllib的urlencode()函数的编码和解码功能。还分别讲解了GET和POST请求方式,给出批量爬取贴吧页面数据的实例,最后提到了HTTPS请求的SSL证书验证问题。

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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值