Python 正在从网络抓取中下载数据文件 URL

Python Downloading Data File from Web-Scraped URL

我正在尝试开发一个自动化脚本来将以下数据文件下载到实用程序服务器,然后进行 ETL 相关处理。寻找 pythonic 建议。不熟悉 urllib、urllib2、beautiful soup、requests、mechanize、selenium 等之间当前此类进程的最佳选择

The Website

"Full Replacement Monthly NPI File"

The Monthly Data File

文件名(以及后续 url)每月更改一次。

这是我目前的方法:

from bs4 import BeautifulSoup
import urllib 
import urllib2

soup = BeautifulSoup(urllib2.urlopen('http://nppes.viva-it.com/NPI_Files.html').read())

download_links = []

for link in soup.findAll(href=True):
    urls = link.get('href', '/')
    download_links.append(urls)

target_url = download_links[2]

urllib.urlretrieve(target_url , "NPI.zip")

我不期待这个笨拙的政府的内容。要更改的站点,所以我虽然只选择已抓取的 url 列表的第三个元素就足够了。当然,如果我的整个做法是错误的,欢迎指正(数据分析是个人强项)。另外,如果我使用的是过时的库、非 Python 实践或低性能选项,我绝对欢迎更新更好的!

一般来说requests是获取网页的最简单方法。

如果数据文件的名称遵循模式 NPPES_Data_Dissemination_<Month>_<year>.zip,这似乎符合逻辑,您可以直接请求;

import requests

url = "http://nppes.viva-it.com/NPPES_Data_Dissemination_{}_{}.zip"
r = requests.get(url.format("March", 2015))

然后数据在r.text.

如果数据文件名不太确定,可以获取网页,使用正则表达式搜索指向zip个文件的链接;

In [1]: import requests

In [2]: r = requests.get('http://nppes.viva-it.com/NPI_Files.html')

In [3]: import re

In [4]: re.findall('http.*NPPES.*\.zip', r.text)
Out[4]: 
['http://nppes.viva-it.com/NPPES_Data_Dissemination_March_2015.zip',
 'http://nppes.viva-it.com/NPPES_Deactivated_NPI_Report_031015.zip',
 'http://nppes.viva-it.com/NPPES_Data_Dissemination_030915_031515_Weekly.zip',
 'http://nppes.viva-it.com/NPPES_Data_Dissemination_031615_032215_Weekly.zip',
 'http://nppes.viva-it.com/NPPES_Data_Dissemination_032315_032915_Weekly.zip',
 'http://nppes.viva-it.com/NPPES_Data_Dissemination_033015_040515_Weekly.zip',
 'http://nppes.viva-it.com/NPPES_Data_Dissemination_100614_101214_Weekly.zip']

In[4] 中的正则表达式基本上表示查找以 "http" 开头、包含 "NPPES" 并以“.zip”结尾的字符串。 这不够具体。让我们更改正则表达式,如下所示;

In [5]: re.findall('http.*NPPES_Data_Dissemination.*\.zip', r.text)
Out[5]: 
['http://nppes.viva-it.com/NPPES_Data_Dissemination_March_2015.zip',
 'http://nppes.viva-it.com/NPPES_Data_Dissemination_030915_031515_Weekly.zip',
 'http://nppes.viva-it.com/NPPES_Data_Dissemination_031615_032215_Weekly.zip',
 'http://nppes.viva-it.com/NPPES_Data_Dissemination_032315_032915_Weekly.zip',
 'http://nppes.viva-it.com/NPPES_Data_Dissemination_033015_040515_Weekly.zip',
 'http://nppes.viva-it.com/NPPES_Data_Dissemination_100614_101214_Weekly.zip']

这为我们提供了我们想要的文件的 URLs 以及每周文件。

In [6]: fileURLS = re.findall('http.*NPPES_Data_Dissemination.*\.zip', r.text)

让我们筛选出每周文件:

In [7]: [f for f in fileURLS if 'Weekly' not in f]
Out[7]: ['http://nppes.viva-it.com/NPPES_Data_Dissemination_March_2015.zip']

这就是您要找的URL。但是整个方案确实取决于名称的规律性。您可以向正则表达式搜索添加标志以丢弃字母的大小写,这将使其接受更多。