【学习笔记2】get与post请求对象的定制

一、请求对象的定制

1.URL的组成

 url的组成
# 协议,主机,端口号 路径 参数 锚点
# 端口号:http 80 https 443 mysql 3306 oracle 1521 redis 6379 mongodb 27017
# https://www.baidu.com/s?wd=%E5%91%A8%E6%9D%B0%E4%BC%A6
                            # s 路径 wd = 周杰伦

2.UA介绍

User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本。浏览器内核、浏览器渲染引擎、浏览器语言、浏览器插件等

3.代码实现请求对象的定制

import urllib.request
import requests
url = 'https://www.baidu.com'
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.55"
}
# urlopen方法中不能存储字典,所以headers不能传递进去
# 请求对象的定制
request = urllib.request.Request(url = url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(content)

二、get请求

1.编解码

‘’‘编码集的演变 :
由于计算机是美国人发明的,因此,最早只有127个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号,
这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122。
但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,
所以,中国制定了GB2312编码,用来把中文编进去。
你可以想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc‐kr里,
各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。
因此,Unicode应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。
Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。
现代操作系统和大多数编程语言都直接支持Unicode。’‘’

2.get请求方式:urllib.parse.quote()

作用:通过Unicode将中文编码为Unicode字符

import urllib.request
import urllib.parse
url = 'https://www.baidu.com/s?wd='
headers = {
'User‐Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/74.0.3729.169 Safari/537.36'
}
url = url + urllib.parse.quote('小野')
request = urllib.request.Request(url=url,headers=headers)
response = urllib.request.urlopen(request)
print(response.read().decode('utf‐8'))

3.get请求方式:urllib.parse.urlencode()

应用场景:有多个需要转码的数据,可以通过urlencode()方法批量编码

import urllib.request
import urllib.parse
# url = 'https://www.baidu.com/s?wd=周杰伦&sex=男'
data = {
    'wd' : '周杰伦',
    'sex': '男',
    'location': '中国台湾'
}
base_url ='https://www.baidu.com/s?'
new_url = base_url + urllib.parse.urlencode(data)
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.55"
}
# 请求对象定制
request = urllib.request.Request(url=new_url,headers=headers)
# 模拟浏览器向服务器发送请求并将获得的内容保存到response中
response = urllib.request.urlopen(request)
# 获取网页源码数据
content = response.read().decode('utf-8')
print(content)

三、post请求

1.post请求的概念

POST:就是发送、提交。向服务器提交/发送要被处理的数据。
所以我们在写Python爬虫程序时需要向服务器发送“被处理的数据”

2.代码实现请求过程

# post请求
import urllib.request
import urllib.parse

url = 'https://fanyi.baidu.com/sug'
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.55"
}
data = {
    'kw' : 'spider'
}
# post请求的参数,必须要进行编码
# TypeError: POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type str.
# data = urllib.parse.urlencode(data)
# urlencode的作用是将中文转换为unicode编码,接着再使用encode进行utf编码转化字符串
data = urllib.parse.urlencode(data).encode('utf-8')
# post请求的参数,不拼接在URL后面,而是放在请求对象的定制里
request = urllib.request.Request(url=url,data=data,headers=headers)
# 模拟浏览器向服务器发起请求
reponse = urllib.request.urlopen(request)
# 获取相应的数据
content = reponse.read().decode('utf-8')
# print(content)
# print(type(content)) //str
import json
# 字符串转json对象
obj = json.loads(content)
print(obj)

2.1 注意点

1. post请求的参数,必须要进行编码,否则会弹出以下报错
TypeError: POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type str.
data = urllib.parse.urlencode(data)

2. urlencode的作用是将中文转换为unicode编码,接着再使用encode进行utf编码转化字符串
data = urllib.parse.urlencode(data).encode(‘utf-8’)
post请求的参数,不拼接在URL后面,而是放在请求对象的定制里

3.百度翻译之详细翻译

3.1 找到百度翻译的详细翻译请求连接

在这里插入图片描述

3.2 找到请求头数据

没有描述

3.3 具体代码实现

import urllib.request
import urllib.parse
# pycharm中CTRL+R,点击正则,(.*): (.*)替换为'$1': '$2',
url = 'https://fanyi.baidu.com/v2transapi?from=en&to=zh'

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.55",
    'Cookie':'BIDUPSID=1F517093F82AB0ACD13B28A86CA84B92; PSTM=1663416938; BAIDUID=639E62E23593EC42203AB431064FCDAA:FG=1; __yjs_duid=1_eb03bf7c19c71fe48f4b810c43c510301664701456061; APPGUIDE_10_0_2=1; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; newlogin=1; BDUSS=352cjlZcFRMdHU0SlN3dVBMS2hQTURZUmJmTU1YcWhQd2ZISmdrNHZweWZGOTVqRVFBQUFBJCQAAAAAAQAAAAEAAACJyTUR06a8scqzxrcxMTQ1MTQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ-KtmOfirZja; BDUSS_BFESS=352cjlZcFRMdHU0SlN3dVBMS2hQTURZUmJmTU1YcWhQd2ZISmdrNHZweWZGOTVqRVFBQUFBJCQAAAAAAQAAAAEAAACJyTUR06a8scqzxrcxMTQ1MTQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ-KtmOfirZja; BAIDUID_BFESS=639E62E23593EC42203AB431064FCDAA:FG=1; BAIDU_WISE_UID=wapp_1677402783202_998; __bid_n=1869d22e7f6289f5fd4207; FPTOKEN=etU9iptHzgCmwCOqMOOfkcyi63cU0uh8b2W0vUJ5sB67OdXyf/B2hxe+BtnKC+djVoEUQphdgq0Hlyxic8ewiJUg7XL3YasGQcP/ZC5ztv+yIXKvL88OO2DmGVRaPVQY9DOZJy+R54X9mkrOmhS5DDvhvvJzxisqW72zOa5Y/yzohxIlPZmzOJsez63w5AzvlYKKNmDpX22SPLNoY+YHoQ3LyubRqTxmupDNmZcbajD4y2vdv7HGhf1XlkhTKtf7jJBZDIOGVa8dJ7NVPSCGGaspf6Ls1jw6zL1PQye7jUWWpF9NBhhyesJ1JPFSh7zJ+rrtRE2e+qAKVlSHMoS85XN3dGIxm3ty5E6ZnfGz7wn2HWlemDJ/u4EQjq1le5s8wpUTMoOQ9ox0CgAHB9miUQ==|0WTYVih31lqesLLyeSABKzv7epY8LWheqLP7yD7VzY8=|10|90ea37aa7e8b08034ed5bc703c027763; BA_HECTOR=008k002g2h2h048l842g05771i12ufl1m; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; ZFY=Sbsk2IiC3KnpbsVHnPmf4osSjH:BxIkUFgKxcQ4H5LC8:C; BDRCVFR[feWj1Vr5u3D]=mk3SLVN4HKm; delPer=0; PSINO=7; H_PS_PSSID=38185_36551_37553_38106_38126_38171_38289_38380_37936_38313_38382_38285_37900_26350_37958_22159_38281_37881; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1678609556,1678611329,1678617365,1678878409; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1678880222; ab_sr=1.0.1_ZTVkMjk4ODQ0ZWM2ZDA5MTA5ZTFkNzQxN2IzYTVjZTJlMDU2Zjk1NzcyNTQxMzg4NDkwY2U3Y2U1N2FiYjIzNWI4ZDAzOTYyMGU4NTMxN2FlNTU2MTY0NGYzYWQxY2Q5MTNlZTZmNThlYzYwMTQwYzBlM2Y1OWJmMGMyOTcxMzkzNGQzMmY1ZWM3MmZmOWZiNzY4MTA3MDM1ZGVmZTNkNmZjMzQ2OTE5MTM3MzYzYmVlZDg4OTcyOGJlMjk2NzQ2'}

data = {
    'from': 'en',
    'to': 'zh',
    'query': 'love',
    'transtype': 'realtime',
    'simple_means_flag': '3',
    'sign': '198772.518981',
    'token': 'b7cdbd1292586a94fb077e8358f97693',
    'domain': 'common'
}
# post的请求参数必须进行编码,并且要调用encode编码
data = urllib.parse.urlencode(data).encode('utf-8')
# 请求对象的定制
request = urllib.request.Request(url=url,data=data,headers=headers)
reponse = urllib.request.urlopen(request)
content = reponse.read().decode('utf-8')
# print(content)
import json
obj = json.loads(content)
print(obj)

四、Ajax的get请求

1.豆瓣电影案例

1.1 考察要点

1. 爬取网站不同页数的内容,关键点在于url后面的start和limit参数
2. get请求方式的特点就是在于url地址后面跟着的一系列参数的编码
3. 所以利用好urlencode()方法是Ajax Get请求的核心

1.2 具体代码实现

import json
import urllib.request
import urllib.parse

# url = 'https://movie.douban.com/j/chart/top_list?type=5&interval_id=100:90&action=&start=0&'
# strat = 'limit=20'
# 1、请求对象定制(url,UA,post请求方法中url和data分开)
# 2、传入请求对象,获取数据
# 3、得到数据进行读取.decode
# 4、进行数据的下载

def create_request(page):
    base_url = 'https://movie.douban.com/j/chart/top_list?type=5&interval_id=100:90&action=&'
    data = {
        'start' : (page - 1) * 20,
        'limit' : 20
    }

    data = urllib.parse.urlencode(data)

    new_url = base_url + data

    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.55"
    }
    # 请求对象定制
    request = urllib.request.Request(url=new_url,headers=headers)
    return request
def get_content(request):
    reponse = urllib.request.urlopen(request)
    content = reponse.read().decode('utf-8')
    return content

def down_load(page,content):
    fp =  open(f'douban{page}.json','w',encoding='utf-8')
    print(f'正在下载第{page}页')
    fp.write(content)
    print(f'第{page}页数据下载成功')
    fp.flush()
    fp.close()

if __name__ == '__main__':
    start_page = int(input('请输入起始页数:'))
    end_page = int(input('请输入结束的页数:'))
    for page in range(start_page,end_page + 1):
        # 每一页都有请求对象的定制
        request = create_request(page)
        # 获取响应的数据
        content = get_content(request)
        #下载数据
        down_load(page,content)
print('下载结束')

五、Ajax的post请求

1.肯德基餐厅位置案例

1.1 考察要点

1. POST请求的关键点在于:发送数据
2. 此时变量在于POST发送的数据
3. 点我传送:肯德基餐厅查询地址在这里插入图片描述

1.2 具体代码实现

# url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname'
# 第一页:
# cname: 北京
# pid:
# pageIndex: 1
# pageSize: 10

# url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname'
# 第二页:
# cname: 北京
# pid:
# pageIndex: 2
# pageSize: 10
import urllib.request
import urllib.parse
def create_request(page,cname):
    url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname'
    data = {
        'cname': cname,
        'pageIndex': page,
        'pageSize': '10'
    }
    #一个urlencode编码和encode编码
    data = urllib.parse.urlencode(data).encode('utf-8')

    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.55"
    }
    # 请求对象定制
    request = urllib.request.Request(url=url,data=data,headers=headers)
    return request
def get_content(request):
    response = urllib.request.urlopen(request)
    # 一个decode解码
    content = response.read().decode('utf-8')
    return content
def down_load(page,content):
    with open(f'{cname}{page}.json','w',encoding='utf-8') as fp:
        print(f'正在下载第{page}页')
        fp.write(content)
        print(f'第{page}页数据下载成功')
        fp.flush()

if __name__ == '__main__':
    start_page = int(input('请输入起始页数:'))
    end_page = int(input('请输入结束的页数:'))
    cname = input('请输入想查询的城市:')
    for page in range(start_page,end_page +1 ):
        # 每一页都有请求对象的定制
        request = create_request(page,cname)
        # 获取响应的数据
        content = get_content(request)
        #下载数据
        down_load(page,content)

print('下载完成')
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值