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

Scrapy中multipart/form-data请求字符异常及正确使用方法问询

解决Scrapy中multipart/form-data字符转义问题

你遇到的问题核心是手动构造请求body时,Python会自动解析字符串中的转义字符,比如你写的\\wcp01zfs-03.clerk.local\files2\ORISPDF\,实际发送时会被转成\wcp01zfs-03.clerk.localfiles2ORISPDF\(因为\f是Python的换页符转义序列),这和浏览器发送的原始数据完全不一致,最终导致请求失败。

别再手动拼接multipart请求体了——Scrapy提供了更可靠的方式来处理表单提交,推荐使用FormRequest类自动处理编码、边界生成和字符转义,完全贴合浏览器的请求行为。

方案1:用FormRequest.from_response()自动提取表单

既然页面上已经存在目标表单(就是你提供的courtform),直接用from_response方法自动解析表单的action、enctype和所有字段,只需要替换动态的id和doc_id即可:

def get_image(self, response):
    # 自动解析页面中的courtform表单
    yield scrapy.FormRequest.from_response(
        response,
        formname='courtform',  # 匹配表单的name属性
        formdata={
            'id': response.xpath("//input[@name='doc_id']/@value").extract_first(),
            'doc_id': response.xpath("//input[@name='doc_id']/@value").extract_first()
        },
        callback=self.get_pdf,
        dont_filter=True
    )

这个方法会帮你自动处理multipart/form-data的所有细节,包括边界字符串生成、字段值的正确编码,完全复刻浏览器的请求逻辑。

方案2:手动构造FormRequest

如果需要完全自定义表单字段,可以把所有数据整理成字典,交给FormRequest处理编码:

def get_image(self, response):
    url = 'http://oris.co.palm-beach.fl.us:8080/PdfServlet/PdfServlet27'
    doc_id = response.xpath("//input[@name='doc_id']/@value").extract_first()
    
    # 整理所有表单字段,注意带反斜杠的内容用原始字符串(r'')避免转义
    formdata = {
        'hostURL': 'http://oris.co.palm-beach.fl.us/or_web1/',
        'pdfPath': r'\\wcp01zfs-03.clerk.local\files2\ORISPDF\',
        'pdfURL': 'http://oris.co.palm-beach.fl.us/pdf/',
        'pages': '1',
        'id': doc_id,
        'mpages': '1',
        'doc_id': doc_id,
        'page1': r'image_from_file.asp?imageurl=\\ors_fs\ORImage\O\30338\O.30338.0268.0001.tif',
        'WaterMarkText': '1'
    }
    
    yield scrapy.FormRequest(
        url,
        formdata=formdata,
        # 指定enctype,Scrapy会自动生成正确的边界和请求体
        headers={'Content-Type': 'multipart/form-data'},
        callback=self.get_pdf,
        dont_filter=True
    )

如果你坚持手动构造body(不推荐)

如果一定要自己写body字符串,必须用原始字符串(在字符串前加r),这样Python不会解析里面的转义字符:

def get_image(self, response):
    url = 'http://oris.co.palm-beach.fl.us:8080/PdfServlet/PdfServlet27'
    doc_id = response.xpath("//input[@name='doc_id']/@value").extract_first()
    
    # 用r''定义原始字符串,避免转义字符被解析
    body = r'''------WebKitFormBoundarysGRfL8zMeuSs4zsH
Content-Disposition: form-data; name="hostURL"
http://oris.co.palm-beach.fl.us/or_web1/
------WebKitFormBoundarysGRfL8zMeuSs4zsH
Content-Disposition: form-data; name="pdfPath"
\\wcp01zfs-03.clerk.local\files2\ORISPDF\
------WebKitFormBoundarysGRfL8zMeuSs4zsH
Content-Disposition: form-data; name="pdfURL"
http://oris.co.palm-beach.fl.us/pdf/
------WebKitFormBoundarysGRfL8zMeuSs4zsH
Content-Disposition: form-data; name="pages"
1
------WebKitFormBoundarysGRfL8zMeuSs4zsH
Content-Disposition: form-data; name="id"
{}
------WebKitFormBoundarysGRfL8zMeuSs4zsH
Content-Disposition: form-data; name="mpages"
1
------WebKitFormBoundarysGRfL8zMeuSs4zsH
Content-Disposition: form-data; name="doc_id"
{}
------WebKitFormBoundarysGRfL8zMeuSs4zsH
Content-Disposition: form-data; name="page1"
image_from_file.asp?imageurl=\\ors_fs\ORImage\O\30338\O.30338.0268.0001.tif
------WebKitFormBoundarysGRfL8zMeuSs4zsH
Content-Disposition: form-data; name="WaterMarkText"
1
------WebKitFormBoundarysGRfL8zMeuSs4zsH--'''.format(doc_id, doc_id)
    
    headers = {
        'origin': "http://oris.co.palm-beach.fl.us",
        'upgrade-insecure-requests': "1",
        'dnt': "1",
        'content-type': "multipart/form-data; boundary=----WebKitFormBoundarysGRfL8zMeuSs4zsH",
        'user-agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36",
        'accept': "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
        'cache-control': "no-cache",
    }
    
    r = scrapy.Request(url, method="POST", headers=headers, body=body, callback=self.get_pdf, dont_filter=True)
    yield r

不过这种方式很容易出错,比如边界字符串和headers里的不一致、换行符格式不匹配等,所以优先推荐前两种FormRequest的方案。

内容的提问来源于stack exchange,提问作者JBJ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:50:28