能否用Python自动化下载BHC官网判决PDF?求实现方案
巴基斯坦高等法院判决PDF自动化下载的Python实现方案
可以用Python实现这个自动化下载流程,核心是模拟浏览器的会话流程和请求特征,绕过网站的访问限制。以下是具体的技术方案和代码示例:
核心逻辑拆解
网站的限制主要是会话验证:必须先通过POST请求进入目标页面,建立合法会话后,才能触发下载API的GET请求。直接调用下载API会因为缺少会话Cookie或Referer验证被拦截。
关键实现步骤
- 维持会话状态
使用requests.Session()全程管理Cookie和会话信息,确保所有请求共享同一个会话上下文,这是绕过访问限制的核心。 - 模拟浏览器请求头
完全照搬浏览器的请求头(从你提供的截图中提取),至少包含User-Agent、Referer、Cookie、Accept这些字段,网站会通过这些字段验证请求合法性。 - 先完成POST跳转
先发送POST请求进入判决列表页面,让网站生成并记录你的会话状态,之后的下载请求才能通过验证。 - 分块下载PDF
下载时使用stream=True参数分块写入文件,避免大文件占用过多内存。
可运行代码示例
import requests from bs4 import BeautifulSoup import time import random # 初始化会话,复用Cookie session = requests.Session() # 模拟真实浏览器的请求头(从浏览器开发者工具复制完整字段) BASE_HEADERS = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.9", "Accept-Encoding": "gzip, deflate, br", "Connection": "keep-alive", } def init_session(): # 先访问首页,获取初始Cookie session.get("https://portal.bhc.gov.pk/judgments/", headers=BASE_HEADERS) def get_judgment_list(post_params): # 发送POST请求获取判决列表页面 post_url = "https://portal.bhc.gov.pk/judgments/search_results" response = session.post(post_url, data=post_params, headers=BASE_HEADERS) response.raise_for_status() # 捕获请求错误 return response.text def download_pdfs(page_html): soup = BeautifulSoup(page_html, "html.parser") download_links = soup.find_all("a", href=True, string="Download PDF") for idx, link in enumerate(download_links): # 构造完整的下载API URL download_url = f"https://portal.bhc.gov.pk{link['href']}" # 更新Referer为列表页面URL,确保验证通过 download_headers = BASE_HEADERS.copy() download_headers["Referer"] = "https://portal.bhc.gov.pk/judgments/search_results" try: # 发送下载请求,分块写入 with session.get(download_url, headers=download_headers, stream=True) as resp: resp.raise_for_status() # 从URL提取文件名,或从响应头获取 filename = f"judgment_{idx+1}.pdf" with open(filename, "wb") as f: for chunk in resp.iter_content(chunk_size=8192): f.write(chunk) print(f"✅ 已下载:{filename}") except Exception as e: print(f"❌ 下载失败 {download_url}:{str(e)}") # 添加随机延迟,避免触发反爬 time.sleep(random.uniform(1.5, 3)) if __name__ == "__main__": # 替换为你需要查询的表单参数(从浏览器抓包获取) search_params = { "case_type": "1", "year": "2024", "judge": "", "case_no": "" } init_session() judgment_page = get_judgment_list(search_params) download_pdfs(judgment_page)
应对访问限制的额外建议
- 请求头要完整:不要只带
User-Agent,务必复制浏览器中的所有请求头字段,尤其是Referer和Cookie,这是网站验证会话的关键。 - 控制请求频率:添加随机延迟(代码中已包含),短时间内大量请求会直接封禁IP。
- 处理验证码:如果遇到验证码,可集成
pytesseract做简单OCR识别,或者手动输入验证码后继续会话。 - 代理IP轮换:如果IP被封禁,可使用代理IP池轮换请求,避免单一IP被限制。
- 抓包验证:如果请求失败,对比浏览器的请求和代码中的请求,检查Cookie、请求头、参数是否完全一致,这是排查问题的核心方法。
内容的提问来源于stack exchange,提问作者Imran
相关产品推荐
相关产品推荐

