爬虫 | urllib.parse

# CY3761 | 2021-12-23 11:50
import os.path
import types
from urllib import parse

upDict = parse.__dict__
upDictKeys = upDict.keys()

"""
print('-' * 80)
print('parse.__dict__(keys)')
[print(str(k).zfill(2), _) for k, _ in enumerate(upDictKeys) if not _.startswith('_')]
"""

"""
print('-' * 80)
[print(str(k).zfill(2), _) for k, _ in enumerate(upDict.items()) if not _[0].startswith('_')]  # 过滤私有
"""

"""
print('-' * 80)
[print(str(k).zfill(2), _) for k, _ in enumerate(upDict.items())
        if not _[0].startswith('_') and isinstance(_[1], types.FunctionType)]  # 过滤私有, 可调用的
"""
filePath = 'parse-func.txt'
if not os.path.exists(filePath):
    with open(filePath, 'w', encoding='utf-8') as w:
        [w.write(_[0] + '\n') for k, _ in enumerate(upDict.items())
         if not _[0].startswith('_') and isinstance(_[1], types.FunctionType)]  # 过滤私有, 可调用的

# https://docs.python.org/zh-cn/3.9/library/urllib.parse.html#urllib.parse.urlunparse
# 01 parse.urlparse 与 parse.urlsplit
u = 'https://www.baidu.com:80/s?wd=python&username=abc#1'

"""
scheme(请求协议) : 一般 http/https
netloc(请求域名)
path(请求路径[路由])
query(请求GET参数)
fragment(描点): URL #后的字符串
params: 提交数据, 感觉值传入一个URL视为空 (urlparse具有该属性)
port(端口号): 没提供返回None
"""

# scheme='https', netloc='www.baidu.com:80', path='/s', params='', query='wd=python&username=abc', fragment='1', port=80

print('-' * 80)
pup = parse.urlparse(u)
pus = parse.urlsplit(u)
print('parse.urlparse', pup, pup.port)  # ParseResult(scheme, netloc, path, params, query, fragment) 80
print('parse.urlsplit', pus, pus.port)  # SplitResult(scheme, netloc, path, query, fragment)

# 02 parse.urlunparse 与 parse.urlunsplit
"""

urllib.parse.urlunparse(parts)
根据 urlparse() 所返回的元组来构造一个 URL. parts 参数可以是任何包含六个条目的可迭代对象.
构造的结果可能是略有不同但保持等价的 URL, 如果被解析的 URL 原本包含不必要的分隔符(例如,带有空查询的 ?;RFC 已声明这是等价的)
"""
print('-' * 80)
print('parse.urlunparse', parse.urlunparse(pup))  # https://www.baidu.com:80/s?wd=python&username=abc#1
print('parse.urlunsplit', parse.urlunsplit(pus))  # https://www.baidu.com:80/s?wd=python&username=abc#1

# 03 parse.parse_qs 与 parse.parse_qsl
q = 'name=Tom&name=Jack&age=13&school=&home&cn=中文&msg=hello world'
print('-' * 80)

pqd = parse.parse_qs(q)
pql = parse.parse_qsl(q)
print(pqd)  # 返回JSON {'k1':['v1','v2'],...} 字符串具有多个相同的参数则返回多个参数值(在列表中..) v为字符串
print(pql)  # 返回列表 [('k1', 'v1'), ('k2', 'v2'), ...] v为字符串

"""
URL 转码
"""
print('-' * 80)
pqu = parse.quote(q)
pqup = parse.quote_plus(q)
print(pqu)  # 转码为 %xx 形式的字符串 (完全转换, 包括=&)
print(pqup)  # 转码为 %xx 形式的字符串, 空格使用 + 代替 (完全转换, 包括=&)

# unquote
print('-' * 80)
print(parse.unquote(pqu))  # 将转码后的字符串进行解码
print(parse.unquote_plus(pqup))  # 专门处理 parse.quote_plus 结果的解码

print(parse.urlencode({k: v[0] for (k, v) in pqd.items()}))  # 参数传入字典, 对中文等进行转码 (正常转换, 不处理=&)

# 官方文档源码: https://github.com/python/cpython/tree/3.9/Doc

print('-' * 80)
u = ('https://image.baidu.com/search/acjson?tn=resultjson_com&logid=10363389854672847255&ipn=rj&ct=201326592&is='
     '&fp=result&queryWord=%E7%BE%8E%E5%A5%B3&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&hd=&latest='
     '&copyright=&word=%E7%BE%8E%E5%A5%B3&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&expermode='
     '&nojc=&cg=girl&pn=30&rn=30&gsm=1e&1635132340880=')

pup = parse.urlparse(u)
pupQuery = pup.query

[print(k, v[0]) for (k, v) in parse.parse_qs(pupQuery).items()]

"""
返回 GET参数数据
{'tn': 'resultjson_com', 'logid': '10363389854672847255', 'ipn': 'rj', 'ct': '201326592', 'fp': 'result',
'queryWord': '美女', 'cl': '2', 'lm': '-1', 'ie': 'utf-8', 'oe': 'utf-8', 'st': '-1', 'ic': '0', 'word': '美女',
'face': '0', 'istype': '2', 'nc': '1', 'cg': 'girl', 'pn': '30', 'rn': '30', 'gsm': '1e'}
"""

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CY3761

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值