You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否用Python自动化下载BHC官网判决PDF?求实现方案

巴基斯坦高等法院判决PDF自动化下载的Python实现方案

可以用Python实现这个自动化下载流程,核心是模拟浏览器的会话流程和请求特征,绕过网站的访问限制。以下是具体的技术方案和代码示例:

核心逻辑拆解

网站的限制主要是会话验证:必须先通过POST请求进入目标页面,建立合法会话后,才能触发下载API的GET请求。直接调用下载API会因为缺少会话Cookie或Referer验证被拦截。

关键实现步骤

  1. 维持会话状态
    使用requests.Session()全程管理Cookie和会话信息,确保所有请求共享同一个会话上下文,这是绕过访问限制的核心。
  2. 模拟浏览器请求头
    完全照搬浏览器的请求头(从你提供的截图中提取),至少包含User-Agent、Referer、Cookie、Accept这些字段,网站会通过这些字段验证请求合法性。
  3. 先完成POST跳转
    先发送POST请求进入判决列表页面,让网站生成并记录你的会话状态,之后的下载请求才能通过验证。
  4. 分块下载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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 09:03:09