BeatuifulSoup 从欧洲志愿服务获取数据并解析:一个从 EU-Site 收集机会的小型抓取工具

问题描述 投票:0回答:1

正在寻找欧洲志愿服务的公开列表:我不需要完整的地址 - 但需要名称和网站。我认为数据... XML、CSV ... 具有这些字段:名称、国家/地区 - 以及一些其他字段,对于每个存在国家/地区来说,一条记录会很好。 顺便说一句:欧洲志愿服务是年轻人的绝佳选择

我发现了一个很棒的页面,非常非常全面 - 请参阅

想要从欧洲网站上托管的欧洲志愿服务收集数据:

https://youth.europa.eu/go-abroad/volunteering/opportunities_en

我们在那里有数百个志愿服务机会 - 这些机会存储在如下网站中:

 https://youth.europa.eu/solidarity/placement/39020_en 

https://youth.europa.eu/solidarity/placement/38993_en 

https://youth.europa.eu/solidarity/placement/38973_en 

https://youth.europa.eu/solidarity/placement/38972_en 

https://youth.europa.eu/solidarity/placement/38850_en 

https://youth.europa.eu/solidarity/placement/38633_en

想法:

我认为收集数据会很棒 - 即使用基于 BS4 和请求的抓取器 - 解析数据并随后在 df 中打印数据

嗯 - 我认为我们可以迭代所有的网址

placement/39020_en 
placement/38993_en 
placement/38973_en 
placement/38850_en 

我认为我们可以在存储中从 0 迭代到 100 000 次以获取存储在展示位置中的所有结果。但这个想法没有代码支持。换句话说 - 目前我不知道如何实现在如此大的范围内迭代的特殊想法:

目前我认为 - 这是从这个开始的基本方法

import requests
from bs4 import BeautifulSoup
import pandas as pd

# List of URLs to scrape
urls = [
    "https://youth.europa.eu/solidarity/placement/39020_en",
    "https://youth.europa.eu/solidarity/placement/38993_en",
    "https://youth.europa.eu/solidarity/placement/38973_en",
    "https://youth.europa.eu/solidarity/placement/38972_en",
    "https://youth.europa.eu/solidarity/placement/38850_en",
    "https://youth.europa.eu/solidarity/placement/38633_en"
]

# Function to scrape data from a single URL
def scrape_data(url):
    response = requests.get(url)
    soup = BeautifulSoup(response.content, 'html.parser')
    
    # Extracting relevant data
    title = soup.find("h2").text.strip()
    location = soup.find("span", class_="field--name-field-placement-location").text.strip()
    start_date = soup.find("span", class_="field--name-field-placement-start-date").text.strip()
    end_date = soup.find("span", class_="field--name-field-placement-end-date").text.strip()
    
    # Returning data as dictionary
    return {
        "Title": title,
        "Location": location,
        "Start Date": start_date,
        "End Date": end_date,
        "URL": url
    }

# Scrape data from all URLs
data = []
for url in urls:
    data.append(scrape_data(url))

# Convert data to DataFrame
df = pd.DataFrame(data)

# Print DataFrame
print(df)

这给了我以下信息

AttributeError                            Traceback (most recent call last)

<ipython-input-1-e65c612df65e> in <cell line: 37>()
     36 data = []
     37 for url in urls:
---> 38     data.append(scrape_data(url))
     39 
     40 # Convert data to DataFrame

<ipython-input-1-e65c612df65e> in scrape_data(url)
     20     # Extracting relevant data
     21     title = soup.find("h2").text.strip()
---> 22     location = soup.find("span", class_="field--name-field-placement-location").text.strip()
     23     start_date = soup.find("span", class_="field--name-field-placement-start-date").text.strip()
     24     end_date = soup.find("span", class_="field--name-field-placement-end-date").text.strip()

AttributeError: 'NoneType' object has no attribute 'text'
python pandas dataframe web-scraping
1个回答
0
投票

首先检查

response
/
soup
中是否包含要选择的元素;您正在讲话的那些人似乎并不在场。正如@John Gordon 提到的,你的选择没有找到任何东西。

您可以像这样选择元素 - 在这里使用

css selectors

# Extracting relevant data
title = soup.h1.get_text(', ',strip=True)
location = soup.select_one('p:has(i.fa-location-arrow)').get_text(', ',strip=True)
start_date,end_date = (e.get_text(strip=True)for e in soup.select('span.extra strong')[-2:])
标题 地点 开始日期 结束日期 网址
0 支持GOB的可持续园艺项目“Es Viver” c/ Camí des Castell, 53, 07702 Maó, 梅诺卡岛, 西班牙 2024年1月6日 2025年5月31日 https://youth.europa.eu/solidarity/placement/39020_en
1 欧洲志愿服务 VS 人口减少 3.0 47400 梅迪纳德尔坎波(巴利亚多利德),西班牙 2024年5月31日 2025年3月30日 https://youth.europa.eu/solidarity/placement/38993_en
2 支持当地社区:ASMISAF/AUNA Inclusión 西班牙甘迪亚 2024年1月6日 2025年6月30日 https://youth.europa.eu/solidarity/placement/38973_en
3 支持当地社区:Caritas Gandia 西班牙甘迪亚 2024年1月6日 2025年6月30日 https://youth.europa.eu/solidarity/placement/38972_en
4 基于马匹辅助干预+社会服务的教学农场 Masía Cal Taulé s/n, 08673 Serrateix, 西班牙 2024年1月3日 2025年3月31日 https://youth.europa.eu/solidarity/placement/38850_en
5 支持农村地区 Plaza de Tuy, 6, 34440 弗罗米斯塔, 西班牙 2024年4月3日 2024/04/11 https://youth.europa.eu/solidarity/placement/38633_en
© www.soinside.com 2019 - 2024. All rights reserved.