Java API设计实战指南:打造稳健、用户友好的API
共享单车数据获取:网络抓取与API调用实践指南
在当前城市交通体系中,共享单车作为一种绿色、便捷的出行方式,已经深入人们的日常生活。它不仅缓解了短途出行的压力,还为环境保护做出了积极贡献。然而,对于共享单车企业而言,如何精准投放单车以满足用户需求,同时避免资源浪费,是一个亟待解决的问题。特别是在市中心单车过剩,而在恶劣天气下单车使用率骤降的情况下,这一挑战尤为突出。
数据工程师在这一领域扮演着至关重要的角色。他们可以通过专业技术,从互联网中提取和分析关键数据,以优化单车的投放策略。
本文将探讨网络抓取技术和API调用如何相互配合,从百科全书中提取城市相关信息,并通过API获取实时天气数据。结合这些数据,我们可以推断出共享单车的使用模式和需求变化,进而为单车投放提供数据支持。
网络抓取与API调用:数据工程的工具箱
网络抓取技术,作为一种高效的数字化信息检索手段,它就像一个智能助手,能够在网络上自动搜集数据。想象一下,如果你需要从众多杂志中搜集关于人工智能、机器学习、网络安全等主题的文章,而不是手动翻阅和记录,你可以利用网络抓取工具,比如Python中的BeautifulSoup库,来快速、精准地完成这项工作。
API(应用程序编程接口)则是软件应用间交互的规则和协议的集合,它们在软件的后台默默发挥着重要作用,实现应用程序间的无缝集成和数据共享。这可以类比为餐馆的菜单,它提供了可供选择的菜品列表和详细描述。用户点菜的过程,就像是发出一个数据请求,而厨房则根据订单准备相应的菜品。在这个比喻中,API扮演着菜单的角色,而用户的订单则相当于对数据的请求。
API的应用场景非常广泛,包括但不限于:
- 服务间通信:使不同的软件系统能够相互交流信息。
- 数据获取:允许应用程序从服务器获取数据,为用户提供动态更新的内容。
- 功能共享:使得服务能够将其功能与其他应用程序共享,例如将地图服务集成到多个应用程序中。
这些API对于软件的重要性不言而喻,它们促进了跨应用程序的交互和数据共享,极大地丰富了用户的体验。与API相比,网页抓取更多地关注于从网页中提取信息,并将这些信息转换成可用的数据格式。虽然两者都涉及数据的获取和处理,但API侧重于应用程序间的交互和数据共享,而网页抓取则侧重于从网页中提取信息。
下图展示了客户端使用GET请求与API服务器之间的基本交互流程。理解这一过程对于掌握Web应用程序中数据的交换和利用至关重要。
在此关系图的起点,API服务器充当中介。它接收GET请求,对其进行处理,并根据请求的参数确定适当的响应。
GET请求表示来自客户端(如网站或应用程序)向API服务器请求特定数据的查询,在请求之后,图中显示了服务器的响应。首先,发出响应代码,例如200表示成功,404表示未找到。然后,返回响应数据,其中包含客户端请求的信息。
由此可以看出,API与网页抓取的主要区别在于它们访问数据的方式:
- API是访问数据的官方渠道。这就像有一张VIP通行证可以进入一场音乐会,在那里你可以直接获得某些信息。
- 另一方面,网络抓取就像坐在观众席上,记下正在播放的歌曲的歌词。这是一种无需使用官方API即可从网站提取数据的方法。
回到最开始提到的案例中。
城市信息可以从多个途径获取。一种方法是从官方统计等渠道的网站下载CSV文件。但要注意的是,城市信息可能会变动频繁,但网站更新的频率无法保障。
另一个方法是使用百科的数据。大量的用户在定期更新这些信息,所以只需要专注于选择正确的数据。
接下来,以使用BeautifulSoup进行网络抓取为案例。目标是什么?提取关键细节,例如名称、纬度、经度和人口数量,两个充满活力的城市:AAA和XXX。
此处作者使用的是Jupyter Notebook开发环境,对于交互式编程和数据可视化非常出色。当然,其他工具如Atom、Visual Studio Code或IntelliJ IDEA也有自己的优势。
分步Python指南:抓取数据实践
首先,让我们看一下用于推断AAA和XXX数据的代码。在本节中,将介绍构成项目骨干的Python库。
import requests
我们的第一个工具是 requests 库。这是互联网的关键——它帮助我们向网站发送HTTP请求。
from bs4 import BeautifulSoup
接下来,我们从 bs4 包中介绍BeautifulSoup。一旦我们有了目标网页,BeautifulSoup就会解析HTML内容。
import pandas as pd
接下来是 pandas,这是数据科学中不可或缺的库。我们可以将抓取的数据转换为可读的表格,非常适合分析和可视化。
Python中另一个常用的模块是 re 模块。它是一个用于处理正则表达式的库。
import reheaders = {'Accept-Language': 'en-US,en;q=0.8'}
第一步是准备Python环境来接收来自web的数据。我们使用 requests 库来做到这一点,通过将“Accept-Language”设置为英语来确保我们的请求被普遍理解。
接下来,确定城市的URL -AAA。这个URL将成为我们获取丰富信息的门户:
url_aaa = "https://en.wikipedia.org/wiki/aaa"
aaa = requests.get(url_aaa, headers=headers)
发送请求后,检查请求是否成功是至关重要的。状态码为200表示连接成功。
aaa.status_code # Should return 200
现在使用BeautifulSoup解析AAA的网页,将HTML内容转换为我们可以使用的格式。
soup_aaa = BeautifulSoup(aaa.content, "html.parser")
当提取特定数据时,就可以获得我们想要的结果:
- 检索到城市名称和国家,指向我们的研究主题
- 经纬度给了我们地理坐标
- 从人口数量可以看出城市的规模
下面是如何仔细检索这些细节的流程:
A_city = soup_aaa.select(".mw-page-title-main")[0].get_text()
A_country = soup_aaa.select('a[href="/wiki/CCC"]')[0].get_text()
A_latitude = soup_aaa.select(".latitude")[0].get_text()
A_longitude = soup_aaa.select(".longitude")[0].get_text()
A_population = soup_aaa.select('td.infobox-data')[10].get_text()
在成功抓取AAA的数据后,我们将注意力转向XXX,使用相同的技术提取其城市名称、人口、纬度和经度。
和前面一样,使用BeautifulSoup解析XXX的百科页面,收集必要的数据并创建一个DataFrame。
data = {
"City": [FR_city, BR_city],
"Population": [FR_population, BR_population],
"Latitude": [FR_latitude, BR_latitude],
"Longitude": [FR_longitude, BR_longitude],
"Country": [FR_country, BR_country]
}
df = pd.DataFrame(data)
接下来,我们通过微调来优化DataFrame以获得更好的可读性和准确性,以确保我们的数据干净且易于理解。
df['Population'] = pd.to_numeric(df['Population'], errors='coerce')
df['Latitude'] = pd.to_numeric(df['Latitude'], errors='coerce')
df['Longitude'] = pd.to_numeric(df['Longitude'], errors='coerce')
df['City'] = df['City'].astype(str)
# Display the DataFrame
print(df.head)
如果您的目标是在编码过程中获得高水平的舒适性和准确性,并且您有兴趣将方法改进到完美,那么这里有一段利用函数的Python代码。这种方法不仅简化了过程,而且提高了代码的可读性和可重用性。
def scrape_city_data(url):
response = requests.get(url)
if response.status_code == 200:
soup = BeautifulSoup(response.content, "html.parser")
city = soup.title.get_text().split(' - ')[0]
country = soup.select('td.infobox-data a')[0].get_text()
latitude = soup.select('span.latitude')[0].get_text()
longitude = soup.select('span.longitude')[0].get_text()
# Find the population data using provided code
population_element = soup.select_one('th.infobox-header:-soup-contains("Population")')
if population_element:
population = population_element.parent.find_next_sibling().find(string=re.compile(r'\d+'))
if population:
population = int(population)
else:
population = None
data = {
'City': [city],
'Country': [country],
'Latitude': [latitude],
'Longitude': [longitude],
'Population': [population],
}
city_df = pd.DataFrame(data)
return city_df
else:
print("Error:", response.status_code)
return None
# List of German cities ( herre you can add more cities)
german_cities = ['Berlin', 'Frankfurt']
# Create an empty DataFrame with specified columns
german_cities_df = pd.DataFrame(columns=['City', 'Country', 'Latitude', 'Longitude', 'Population'])
# Iterate and scrape data for German cities
for city_name in german_cities:
wiki_link = f"https://en.wikipedia.org/wiki/{city_name}"
city_data = scrape_city_data(wiki_link)
# Append the data to the table
if city_data is not None:
german_cities_df = pd.concat([german_cities_df, city_data], ignore_index=True)
# Display the DataFrame
print(german_cities_df)
通过专业的天气预报API来获取数据
有了地理位置,接下来看下影响共享单车的另一个方面——天气。这部分我们采用调用天气预报API的方式来获取数据。
下面是我们准备的Python函数。这个简洁的代码片段展示了如何以精炼的方式实现强大的功能,无缝地融合了技术性与易用性之间的隔阂。
def fetch_weather_data(API_key, city):
import requests
import pandas as pd
from datetime import datetime
from keys import weather_key
url = f"http://api.openweathermap.org/data/2.5/forecast?q={city}&appid={API_key}&units=metric"
response = requests.get(url)
if response.status_code == 200:
weather_json = response.json()
if "list" in weather_json:
temperature = weather_json["list"][0]["main"]["temp"]
description = weather_json["list"][0]['weather'][0]['description']
feels_like = weather_json["list"][0]["main"].get("feels_like")
wind_speed = weather_json["list"][0]["wind"].get("speed")
return pd.DataFrame({
"city": [city],
"forecast_time": [datetime.now()],
"outlook": [description],
"temperature": [temperature],
"feels_like": [feels_like],
"wind_speed": [wind_speed]
})
else:
print("Unexpected response format: 'list' key not found.")
else:
print(f"Failed to fetch data for {city}. Status Code: {response.status_code}")
return pd.DataFrame()
cities = ["Berlin", "Frankfurt"]
API_key = weather_key # Replace with your actual API key
weather_df = pd.DataFrame()
for city in cities:
city_weather_df = fetch_weather_data(API_key, city)
if not city_weather_df.empty:
weather_df = weather_df.append(city_weather_df, ignore_index=True)
为什么这很重要?
这个DataFrame不仅仅是天气数据的集合,而是Python在将原始数据转换为有意义的见解方面的强大功能。作为一个工具,可以帮助城市居民、旅行者或任何人根据实时天气状况做出决定。
在这篇博客中,我们涉及了抓取百科数据、从API获取天气数据、Python函数以及复杂数据易于理解的技巧。但真正的项目开发中可能会包括对SQL数据库、AWS RDS和Lambda的深入研究,因此本文希望可以让读者明白理论知识和实际应用之间的差距。
声明:本文内容仅做技术学习交流使用。
参考原文及相关资料:
网页抓取和 API:放轻松,这就是数据工程生活方式 |由 Ornela Maloku |2023 年 12 月 |AWS 提示 (awstip.com)