如何使用re.search从requests的response.text中提取HTML内script的hash值
解决方法
1 修复bytes类型匹配报错
TypeError: cannot use a string pattern on a bytes-like object错误的直接原因是:response.content返回的是未解码的字节类型数据,而正则匹配要求输入为字符串类型。
直接将html = response.content替换为html = response.text即可解决,response.text是requests自动解码后的字符串内容。
2 解决未格式化内容匹配失败问题
你保存文件后直接读取匹配失败、手动格式化后才能匹配成功的原因,是原正则表达式硬编码了固定格式:{ "hash":要求大括号后必须有且仅有1个空格,但接口返回的原始内容中,大括号和"hash"之间可能没有空格、有多个空格或者制表符,VSCode格式化时会统一补全/调整空格,所以才会出现格式化后才能匹配的情况。
将正则优化为兼容任意空白符的写法即可,同时限制匹配规则为十六进制字符(hash值均为十六进制),避免误匹配:
# 优化后的正则,\s*匹配任意数量的空白符(包括0个),[a-f0-9]+匹配十六进制hash值 match_obj = re.search(r'"hash"\s*:\s*"([a-f0-9]+)"', html) if match_obj: hash_val = match_obj.group(1)
注意不要用hash作为变量名,它是Python的内置函数名,会产生命名冲突。
3 更稳妥的提取方案
为了避免HTML其他位置出现hash字段导致误匹配,可以先提取最后一个script标签的内容,再在限定范围内做正则匹配:
import re import requests from bs4 import BeautifulSoup # 请求部分 with requests.get(url, headers=headers, cookies=cookies) as response: if response.status_code == 200: html = response.text # 提取所有script标签 soup = BeautifulSoup(html, 'lxml') script_tags = soup.find_all('script') # 取最后一个script的内容 last_script_content = script_tags[-1].string if script_tags else "" if last_script_content: match_obj = re.search(r'"hash"\s*:\s*"([a-f0-9]+)"', last_script_content) if match_obj: hash_val = match_obj.group(1) # 后续业务逻辑
内容的提问来源于stack exchange,提问作者DamianoDoug
相关产品推荐
相关产品推荐

