当 post 带有参数的请求起作用时,无法使用 urllib 从网站下载 csv 文件

Can't download a csv file from a website using urllib, when post requests with parameters comes into play

我正在尝试使用 urllib 包从网页下载 csv 文件。要从该站点下载 csv 文件,需要发送带有适当参数的 post 请求。

当我尝试使用请求模块时,我可以完美地下载文件。然而,当我尝试使用 urllib 包做同样的事情时,我也得到了一个 csv 文件,但这次文件只包含 headers。 body 丢失。

以下是从该站点手动下载该文件的方法:

Site address: https://www.nyiso.com/custom-reports?report=dam_lbmp_zonal
Zones: CAPITL, CENTRL
Version: Latest
Format: CSV
Hit `Generate Report` button

以下脚本仅下载 csv 文件中的 headers:

import csv
import urllib.request
import urllib.parse

link = "http://dss.nyiso.com/dss_oasis/PublicReports"
params = {
    'reportKey': 'DAM_LBMP_ZONE',
    'startDate': '04/17/2021',
    'endDate': '04/17/2021',
    'version': 'L',
    'dataFormat': 'CSV',
    'filter': ['CAPITL','CENTRL'],
}

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36'
}
data = urllib.parse.urlencode(params).encode()
req = urllib.request.Request(link, data=data, headers=headers)
res = urllib.request.urlopen(req)
with open("output.csv","wb") as f:
    f.write(res.read())

How can I download a csv file using urllib package from a website?

代码中的一个小修改,当您在过滤器参数中传递列表时,您需要在 urlencode 方法中传递 doseq=True,同时传递参数以正确编码数据。

参考下面的代码。

import urllib.request
import urllib.parse

link = "http://dss.nyiso.com/dss_oasis/PublicReports"
params = {
    'reportKey': 'DAM_LBMP_ZONE',
    'startDate': '04/17/2021',
    'endDate': '04/17/2021',
    'version': 'L',
    'dataFormat': 'CSV',
    'filter': ['CAPITL','CENTRL'],
}

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36'
}
data = urllib.parse.urlencode(params,doseq=True).encode()
req = urllib.request.Request(link, data=data, headers=headers)
res = urllib.request.urlopen(req)
with open("output.csv","wb") as f:
    f.write(res.read())

只需要对 urlencode 行进行少量修改。

输出:

如果您有任何问题,请告诉我:)