从不同的网站抓取特定的pdf文件



第一个问题。我需要从每个url下载一个特定的pdf。我只需要从我拥有的每个url的欧盟委员会提案的pdf,它总是在页面的特定部分

[这里是我一直需要的pdf格式的网站部分]。欧盟委员会提案

这是它的html代码(我感兴趣的部分是:

"0791 _en.pdf"http://www.europarl.europa.eu/RegData/docs_autres_institutions/commission_europeenne/com/2020/0791/COM_COM (2020);是我需要的pdf,正如你从图片中看到的)

[<a class="externalDocument" href="http://www.europarl.europa.eu/RegData/docs_autres_institutions/commission_europeenne/com/2020/0791/COM_COM(2020)0791_EN.pdf" target="externalDocument">COM(2020)0791</a>, <a href="http://www.europarl.europa.eu/RegData/docs_autres_institutions/commission_europeenne/com/2020/0791/COM_COM(2020)0791_EN.pdf" target="_blank">
<span class="ep_name">
COM(2020)0791
</span>
<span class="ep_icon"> </span>
</a>, <a href="http://www.europarl.europa.eu/RegData/docs_autres_institutions/commission_europeenne/com/2020/0791/COM_COM(2020)0791_EN.pdf" target="_blank">
<span class="ep_name">
COM(2020)0791
</span>
<span class="ep_icon"> </span>
</a>]

我使用了该任务的后续代码,以便它从我的csv文件中获取每个url,并在每个页面中下载每个pdf。问题是,这种方法也需要其他的pdf,我不需要。这对我来说很好,如果它下载它,但我需要区分他们从他们下载的部分,这就是为什么我在这里要求下载所有的pdf从一个特定的小节。因此,如果可以通过部分在名称中区分它们,那也很好,现在这段代码给了我3000个pdf,我需要大约1400个,每个链接一个,如果它保留链接的名称,对我来说也可能更容易,但这不是我主要担心的,因为它们是按照从csv文件中召回的顺序排序的,之后很容易整理它们。

综合而言,这里的代码需要变成只从网站的一部分下载的代码,而不是全部:

import os
import requests
from urllib.parse import urljoin
from bs4 import BeautifulSoup
#import pandas
#data = pandas.read_csv('urls.csv')
#urls = data['urls'].tolist()
urls = ["http://www.europarl.europa.eu/oeil/FindByProcnum.do?lang=en&procnum=OLP/2020/0350", "http://www.europarl.europa.eu/oeil/FindByProcnum.do?lang=en&procnum=OLP/2012/0299", "http://www.europarl.europa.eu/oeil/FindByProcnum.do?lang=en&procnum=OLP/2013/0092"]
#url="http://www.europarl.europa.eu/oeil/FindByProcnum.do?lang=en&procnum=OLP/2013/0092"

folder_location = r'C:UsersmynameDocumentsRwebscraping'
if not os.path.exists(folder_location):os.mkdir(folder_location)
for url in urls:
response = requests.get(url)
soup= BeautifulSoup(response.text, "html.parser")     
for link in soup.select("a[href$='EN.pdf']"):
filename = os.path.join(folder_location,link['href'].split('/')[-1])
with open(filename, 'wb') as f:
f.write(requests.get(urljoin(url,link['href'])).content)
例如,我不想在这里下载这个文件跟进文件这是一个后续文档,以com开头,以EN.pdf结尾,但有一个不同的日期,因为它是一个后续文档(在本例中为2018)。你可以从链接中看到:https://www.europarl.europa.eu/RegData/docs_autres_institutions/commission_europeenne/com/2018/0564/COM_COM (2018) 0564 _en.pdf

html文件中的链接似乎都指向相同的pdf[或至少它们具有相同的文件名],所以它只是下载并覆盖相同的文档。但是,如果您只想瞄准这些链接中的第一个,则可以在选择器中包含externalDocument类。

for link in soup.select('a.externalDocument[href$="EN.pdf"]'):

如果您想针对特定事件,如"立法提案公布">,那么您可以这样做:

# urls....os.mkdir(folder_location)
evtName = 'Legislative proposal published'
tdSel, spSel, aSel = 'div.ep-table-cell', 'span.ep_name', 'a[href$="EN.pdf"]'
dlSel = f'{tdSel}+{tdSel}+{tdSel} {spSel}>{aSel}' 
trSel = f'div.ep-table-row:has(>{dlSel}):has(>{tdSel}+{tdSel} {spSel})'
for url in urls:
response = requests.get(url)
soup= BeautifulSoup(response.text, "html.parser")
pgPdfLinks = [
tr.select_one(dlSel).get('href') for tr in soup.select(trSel) if 
evtName.strip().lower() in 
tr.select_one(f'{tdSel}+{tdSel} {spSel}').get_text().strip().lower()
## if you want [case sensitive] exact match, change condition to
# tr.select_one(f'{tdSel}+{tdSel} {spSel}').get_text() == evtName
]     
for link in pgPdfLinks[:1]:
filename = os.path.join(folder_location, link.split('/')[-1])
with open(filename, 'wb') as f:
f.write(requests.get(urljoin(url, link)).content)

[pgPdfLinks[:1][:1]可能是不必要的,因为不期望有多个匹配,但如果您想绝对确保每个页面只有一次下载,那么它就在那里。]

注意:您需要确保有一个名为evtName的事件,其链接与aSel匹配(在本例中为a[href$="EN.pdf"])—否则,将找不到PDF链接,并且不会为这些页面下载任何内容。


如果它保留链接的名称,这对我来说也可能更容易

它已经在你的代码中这样做了,因为link['href'].split('/')[-1]link.get_text().strip()之间似乎没有太大的区别,但如果你想要页面链接[即url],你可以包括procnum(因为这似乎是url的一个识别部分)在你的filename:

# for link in...
procnum = url.replace('?', '&').split('&procnum=')[-1].split('&')[0]
procnum = ''.join(c if (
c.isalpha() or c.isdigit() or c in '_-[]'
) else ('_' if c == '/' else '') for c in procnum)
filename = f"proc-{procnum} {link.split('/')[-1]}"
# filename = f"proc-{procnum} {link['href'].split('/')[-1]}" # in your current code
filename = os.path.join(folder_location, filename)
with open(filename, 'wb') as f:
f.write(requests.get(urljoin(url, link)).content)
# f.write(requests.get(urljoin(url['href'], link)).content) # in your current code

所以,[例如]不是保存到"COM_COM(2020)0791_EN.pdf">,它将保存到">proc-OLP_2020_0350 COM_COM(2020)0791_EN.pdf"。

我试图通过添加不同的步骤来解决这个问题,以便它可以同时检查pdf来自哪一年并将其添加到名称中。代码如下,这是一个改进,然而,上面的答案由Driftr95比我的好得多,如果有人想复制这个,他们应该使用他的代码。

import requests
import pandas
import os
from urllib.parse import urljoin
from bs4 import BeautifulSoup
data = pandas.read_csv('urls.csv') 
urls = data['url'].tolist()
years = data["yearstr"].tolist()
numbers = data["number"].tolist()
folder_location = r'C:Usersdario.marino5DocumentsRwebscraping'
if not os.path.exists(folder_location):
os.mkdir(folder_location)
for url, year, number in zip(urls, years, numbers):
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")     
for link in soup.select("a[href$='.pdf']"):
if year in link['href']:
# Construct the filename with the number from the CSV file
filename = f'document_{year}_{number}.pdf'
filename = os.path.join(folder_location, filename)
# Download the PDF file and save it to the filename
with open(filename, 'wb') as f:
f.write(requests.get(urljoin(url, link['href'])).content)

最新更新