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

MIT*_*THU 1 python post urllib web-scraping python-3.x

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

当我尝试使用请求模块时,我可以完美地下载文件。但是,当我尝试使用 urllib 包做同样的事情时,我也得到了一个 csv 文件,但这次文件只包含标题。尸体不见了。

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

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

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

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())
Run Code Online (Sandbox Code Playgroud)

如何使用 urllib 包从网站下载 csv 文件?

pb3*_*b36 5

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

请参阅以下代码以供参考。

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())
Run Code Online (Sandbox Code Playgroud)

urlencode生产线上只需要很小的修改。

输出: 输出

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