使用requests模块无法解析后续页面链接的技术求助
问题排查与修正方案
你的脚本无法获取后续页面链接的核心原因是循环中覆盖了report_link变量——初始时report_link是数据接口的URL,但在第一次循环处理数据时,你把它重新赋值为具体报告的完整链接,导致后续的POST请求发到了错误的地址,自然拿不到分页数据。
除此之外,还有几个细节问题会影响脚本稳定性,一并修正如下:
关键修正点
- 重命名具体报告链接的变量,避免覆盖接口URL
- 改用字典传递表单参数,避免手动拼接字符串的编码错误
- 优化异常处理逻辑,精准捕获JSON解析错误,并通过空
data数组判断终止循环 - 简化CSRF Token的处理逻辑(Session会自动维护相关Cookie)
修正后的代码
import requests import json from bs4 import BeautifulSoup base_url = 'https://efdsearch.senate.gov{}' token_page = 'https://efdsearch.senate.gov/search/home/' report_api = 'https://efdsearch.senate.gov/search/report/data/' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36', 'Origin': 'https://efdsearch.senate.gov', 'Referer': 'https://efdsearch.senate.gov/search/', 'Accept': 'application/json, text/javascript, */*; q=0.01', 'X-Requested-With': 'XMLHttpRequest', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' } payload = { 'prohibition_agreement': '1', 'csrfmiddlewaretoken': '' } with requests.Session() as s: s.headers.update(headers) # 获取CSRF Token并提交同意协议 res = s.get(token_page) soup = BeautifulSoup(res.text, "lxml") csrf_token = soup.select_one("input[name='csrfmiddlewaretoken']")['value'] payload['csrfmiddlewaretoken'] = csrf_token s.post(token_page, data=payload) page_start = 0 draw = 0 while True: # 用字典传递参数,避免编码错误 params = { 'draw': str(draw), 'columns[0][data]': '0', 'columns[0][name]': '', 'columns[0][searchable]': 'true', 'columns[0][orderable]': 'true', 'columns[0][search][value]': '', 'columns[0][search][regex]': 'false', 'columns[1][data]': '1', 'columns[1][name]': '', 'columns[1][searchable]': 'true', 'columns[1][orderable]': 'true', 'columns[1][search][value]': '', 'columns[1][search][regex]': 'false', 'columns[2][data]': '2', 'columns[2][name]': '', 'columns[2][searchable]': 'true', 'columns[2][orderable]': 'true', 'columns[2][search][value]': '', 'columns[2][search][regex]': 'false', 'columns[3][data]': '3', 'columns[3][name]': '', 'columns[3][searchable]': 'true', 'columns[3][orderable]': 'true', 'columns[3][search][value]': '', 'columns[3][search][regex]': 'false', 'columns[4][data]': '4', 'columns[4][name]': '', 'columns[4][searchable]': 'true', 'columns[4][orderable]': 'true', 'columns[4][search][value]': '', 'columns[4][search][regex]': 'false', 'order[0][column]': '1', 'order[0][dir]': 'asc', 'order[1][column]': '0', 'order[1][dir]': 'asc', 'start': str(page_start), 'length': '25', 'search[value]': '', 'search[regex]': 'false', 'report_types': '[7, 11, 10, 14]', 'filer_types': '[1]', 'submitted_start_date': '01/01/2023 00:00:00', 'submitted_end_date': '11/30/2023 23:59:59', 'candidate_state': '', 'senator_state': '', 'office_id': '', 'first_name': '', 'last_name': '' } resp = s.post(report_api, data=params) # 精准处理异常与空数据 try: json_data = resp.json() except json.JSONDecodeError: print("请求返回非JSON数据,终止循环") break report_data = json_data.get('data', []) if not report_data: print("无更多数据,终止循环") break # 处理当前页数据,使用新变量存储报告链接 for item in report_data: full_name = item[2] report_soup = BeautifulSoup(item[3], "lxml") report_relative_link = report_soup.select_one("a[href]")['href'] full_report_link = base_url.format(report_relative_link) submit_date = item[4] print(full_report_link) # 更新分页参数 draw = json_data['draw'] + 1 # 按DataTables规范,draw需递增 page_start += 25
内容的提问来源于stack exchange,提问作者MITHU
相关产品推荐
相关产品推荐

