我目前有一个通过抓取生成的数据帧https://www.cve.org/downloads.
Format Unix Compressed (.Z) Gzipped Raw Additional Notes
0 CSV allitems.csv.Z allitems.csv.gz allitems.csv NOTE: suitable for import into spreadsheet pro...
1 HTML allitems.html.Z allitems.html.gz allitems.html NaN
2 Text allitems.txt.Z allitems.txt.gz allitems.txt NaN
3 XML allitems.xml.Z allitems.xml.gz allitems.xml XML Schema Design: cve_1.0.xsd
在Raw栏下,allitems.csv实际上是网站中的一个链接。一旦我将其显示到数据帧中,就无法再访问链接的href
值。以下是我目前使用硒和熊猫的代码:
import pandas as pd
from selenium import webdriver
# from selenium import webdriver
Browser = webdriver.Safari()
# # To navigate to a URL:
Browser.get("http://cve.org/downloads")
# # To get raw html string:
RawHtmlString = Browser.page_source
df = pd.read_html(RawHtmlString)[0]
print(df)
如何编辑我的程序以提取链接并自动下载?
获取链接
如果您真的想提取链接,您可以首先使用attrdata-label="Raw"
获取嵌套在td
中的所有a
标记,然后循环遍历它们并获得hrefs
。例如
raw = Browser.find_elements("xpath", "//td[@data-label='Raw']/a")
links = [r.get_attribute('href') for r in raw]
print(links)
['https://cve.mitre.org/data/downloads/allitems.csv',
'https://cve.mitre.org/data/downloads/allitems.html',
'https://cve.mitre.org/data/downloads/allitems.txt',
'https://cve.mitre.org/data/downloads/allitems.xml']
但如果你只对csv
感兴趣,你可以使用:
csvs = Browser.find_elements(
"xpath", "//td[@data-label='Raw']/a[contains(@href,'.csv')]")
links = [csv.get_attribute('href') for csv in csvs]
# or just use `find_element`, seeing that there is only one such file:
csv_link = Browser.find_element(
"xpath", "//td[@data-label='Raw']/a[contains(@href,'.csv')]")
.get_attribute('href')
当然,在这种特殊情况下,这些都是毫无意义的练习。正如您在上面看到的,所有链接实际上都有相同的基本url。所以,你也可以简单地创建一个额外的列或其他东西:
BASE = 'https://cve.mitre.org/data/downloads/'
df['Urls'] = BASE + df.Raw
print(df.Urls)
0 https://cve.mitre.org/data/downloads/allitems.csv
1 https://cve.mitre.org/data/downloads/allitems....
2 https://cve.mitre.org/data/downloads/allitems.txt
3 https://cve.mitre.org/data/downloads/allitems.xml
Name: Urls, dtype: object
下载文件
对于下载,我会依赖urllib.request
。不过,请注意文档中的警告:;[该函数]可能在将来的某个时刻被弃用">可能。。。这个警告已经存在一段时间了。尝试以下操作:
from urllib import request
my_path = 'destination_folder_path/' # mind the "/" at the end!
for l in links:
fname = l.rsplit('/', maxsplit=1)[1]
print(l) # just to see what we're downloading
request.urlretrieve(l, f'{my_path}{fname}')
首先,您必须访问链接所在的a href
部分,才能获得此文本"/data/downloads/file.csv.gz"
s = requests.Session()
link = '/data/downloads/file.csv.gz'
baseUrl= 'https://cve.mitre.org/'
然后你应用类似的东西
s.get(url=urllib.parse.urljoin(baseurl,file_link),headers=headers)