如何通过requests模块触发USPS打印商目录的Apply Filters按钮?
问题描述
访问指定网页并输入搜索地址New York City, New York, USA后,网页会显示搜索结果,以下Python脚本可实现该基础功能。但现在需要通过Filter results按钮设置筛选条件:
- SERVICES选择
Printing your mailpiece - DISTANCE选择
within 50 miles - SORT选择
By distance
触发Apply Filters按钮完成结果筛选,目前无法用requests模块实现该操作。
原脚本代码:
import time import requests url = 'https://printerdirectory.usps.com/listing/api/vendors' link = 'https://gis.usps.com/arcgis/rest/services/locators/EDDM_Composite/GeocodeServer/suggest' params = { 'text': 'New York City, New York, USA', 'f': 'json' } headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 'Accept': 'application/json, text/plain, */*', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'en-US,en;q=0.9', 'Origin': 'https://printerdirectory.usps.com', 'Referer': 'https://printerdirectory.usps.com/' } result_params = { 'noCache': '' } result_headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 'Accept': 'application/json, text/plain, */*', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'en-US,en;q=0.9', 'Host': 'printerdirectory.usps.com', 'Referer': 'https://printerdirectory.usps.com/listing/', 'Location': '', 'Key': '', 'Type': 'key', 'Lazyupdate': '[object Object]' } with requests.Session() as s: s.headers.update(headers) res = s.get(link,params=params) result_headers['Location'] = res.json()['suggestions'][0]['text'] result_headers['Key'] = res.json()['suggestions'][0]['magicKey'] s.headers.update(result_headers) unixtime = int(time.time()*1000) result_params['noCache'] = unixtime resp = s.get(url,params=result_params) print(resp.json()['vendors'])
请问如何通过requests模块实现Apply Filters按钮的功能?
解决方案
要实现筛选功能,核心是分析网页点击Apply Filters时实际发送的请求参数。通过抓包可以发现,筛选条件是通过GET请求的查询参数传递的,只需在原请求的result_params中添加对应的筛选参数即可:
- 服务筛选参数:
services=Printing your mailpiece - 距离筛选参数:
distance=50(对应within 50 miles) - 排序参数:
sort=distance(对应By distance)
修改后的完整脚本如下:
import time import requests url = 'https://printerdirectory.usps.com/listing/api/vendors' link = 'https://gis.usps.com/arcgis/rest/services/locators/EDDM_Composite/GeocodeServer/suggest' params = { 'text': 'New York City, New York, USA', 'f': 'json' } headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 'Accept': 'application/json, text/plain, */*', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'en-US,en;q=0.9', 'Origin': 'https://printerdirectory.usps.com', 'Referer': 'https://printerdirectory.usps.com/' } # 新增筛选参数 result_params = { 'noCache': '', 'services': 'Printing your mailpiece', 'distance': '50', 'sort': 'distance' } result_headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 'Accept': 'application/json, text/plain, */*', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'en-US,en;q=0.9', 'Host': 'printerdirectory.usps.com', 'Referer': 'https://printerdirectory.usps.com/listing/', 'Location': '', 'Key': '', 'Type': 'key', 'Lazyupdate': '[object Object]' } with requests.Session() as s: s.headers.update(headers) res = s.get(link, params=params) # 处理地址建议为空的情况 if not res.json().get('suggestions'): print("未获取到有效地址建议") exit() result_headers['Location'] = res.json()['suggestions'][0]['text'] result_headers['Key'] = res.json()['suggestions'][0]['magicKey'] s.headers.update(result_headers) unixtime = int(time.time()*1000) result_params['noCache'] = unixtime resp = s.get(url, params=result_params) # 检查请求状态 if resp.status_code == 200: print(resp.json()['vendors']) else: print(f"请求失败,状态码:{resp.status_code}")
补充说明
- 可以通过浏览器开发者工具(F12)抓包,观察点击
Apply Filters时的请求URL,直接提取所需的筛选参数。 - 保持Session会话可维持必要的请求头和状态,避免因请求不完整被服务器拒绝。
- 新增的错误处理逻辑,可避免因地址建议为空或请求失败导致的程序崩溃。
内容的提问来源于stack exchange,提问作者robots.txt
相关产品推荐
相关产品推荐

