数据采集与融合技术实践作业二
作业①:7日天气预报爬取
1. 作业代码与实现步骤
我们将在中国气象网爬取北京、上海、广州的7日天气预报,并将数据保存到数据库中。以下是实现步骤。
Gitee文件夹链接:https://gitee.com/nongchenc/crawl_project/blob/master/作业2/2.1.py
步骤详解
-
打开中国天气网:在浏览器中访问中国天气网。
-
搜索城市:输入“北京”并打开其天气页面。
-
检查网页结构:使用浏览器的开发者工具(按F12)查看网页的HTML结构。
- 每天天气信息存放在一个ul元素的li元素中。
- 日期在li下的h1元素中。
- 天气状态在li下的class为'wea'的p元素文本中。
- 温度信息在class为'tem'下的p元素中的span和i元素中。
-
获取城市编码:北京的城市编码为101010100,据此我们再分别获得上海和广州的城市编码,我们将其存储在字典中,以便构造URL使用。
-
使用BeautifulSoup进行数据爬取:使用CSS选择器查找HTML元素并提取信息。
代码示例
# 给定城市集的城市ID列表(北京、上海、广州)
cities = {
"北京": "101010100",
"上海": "101020100",
"广州": "101280101"
}
# 爬取每个城市的7日天气数据
for city_name, city_id in cities.items():
url = f"http://www.weather.com.cn/weather/{city_id}.shtml"
try:
headers = {"User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.0 x64; en-US; rv:1.9pre) Gecko/2008072421 Minefield/3.0.2pre"}
req = urllib.request.Request(url, headers=headers)
data = urllib.request.urlopen(req)
data = data.read()
dammit = UnicodeDammit(data, ["utf-8", "gbk"])
data = dammit.unicode_markup
soup = BeautifulSoup(data, "lxml")
# 获取7天天气预报信息
lis = soup.select("ul[class='t clearfix'] li")
for li in lis:
try:
date = li.select('h1')[0].text # 获取日期
weather = li.select('p[class="wea"]')[0].text # 获取天气情况
temp_high = li.select('p[class="tem"] span')[0].text if li.select('p[class="tem"] span') else "N/A"
temp_low = li.select('p[class="tem"] i')[0].text
temperature = temp_high + "/" + temp_low # 获取温度(高温/低温)
# 打印天气信息
print(f"{city_name} - {date}: {weather}, {temperature}")
# 将数据插入数据库
c.execute("INSERT INTO weather (city, date, weather, temperature) VALUES (%s, %s, %s, %s)",
(city_name, date, weather, temperature))
conn.commit()
# 关闭数据库连接
conn.close()
print("所有城市的天气数据已保存到数据库!")
图片展示
打印结果
数据库结果
2. 作业心得
在这个作业中,我深入了解了如何从网页中提取结构化数据。通过分析HTML结构,我能够高效地使用CSS选择器定位所需信息,并将其存储在数据库中。此外,学习到城市编码的管理,使我能够灵活处理不同城市的天气数据。这些知识对我今后的学习与实践都大有裨益。
作业②:股票信息爬取
1. 作业代码与实现步骤
接下来,我们将使用requests和BeautifulSoup库爬取东方财富网的股票相关信息,并将其存储到数据库中。
Gitee文件夹链接:https://gitee.com/nongchenc/crawl_project/blob/master/作业2/2.2.py
步骤详解
- 选择股票信息网站:以东方财富网为例,访问 东方财富网。
- 分析网页结构:打开开发者工具(F12),观察股票列表的加载情况。
- 查找数据API:通过网络请求(Network)标签,寻找股票数据的API地址,并分析请求返回的数据格式。
- 提取url,获取单页数据:直接通过requests库的get就可以直接加载数据,对应的文件数据如下。通过分析,我们可以得到单只股票的数据都以字符串的形式被存放在“data”下面,而且控制翻页的参数主要是p参数,所以只要用一个page变量来替代页码,构造新的URL,再通过for循环就能实现提取多页数据。
代码示例
def get_html(cmd, page):
url = f"https://7.push2.eastmoney.com/api/qt/clist/get?cb=jQuery112409467675731682619_1703939377395&pn={page}&pz=20&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&wbp2u=|0|0|0|web&fid={cmd}&fields=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152&_=1703939377396"
response = requests.get(url, headers=header)
data = response.text
left_data = re.search(r'^.*?(?=\()', data).group() # Extracting the callback function name
data = re.sub(left_data + '\(', '', data) # Removing the callback function name
data = re.sub('\);', '', data) # Removing the ending
data = eval(data) # Evaluating the string as a Python expression
return data
cmd = {
"沪深京A股": "f3&fs=m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23,m:0+t:81+s:2048",
}
null = "null"
for market, command in cmd.items():
page = 0
stocks = []
while True:
page += 1
data = get_html(command, page)
if data['data'] != null:
print(f"正在爬取 {market} 第 {page} 页")
df = data['data']['diff']
for index in df:
# 处理数据,确保插入时不出错
#插入的数据会有“-”的出现
latest_price = float(index['f2']) if index['f2'] != '-' else None
change_rate = float(index['f3']) if index['f3'] != '-' else None
change_amount = float(index['f4']) if index['f4'] != '-' else None
volume = float(index['f5']) if index['f5'] != '-' else None
amount = float(index['f6']) if index['f6'] != '-' else None
amplitude = float(index['f7']) if index['f7'] != '-' else None
highest = float(index['f15']) if index['f15'] != '-' else None
lowest = float(index['f16']) if index['f16'] != '-' else None
open_price = float(index['f17']) if index['f17'] != '-' else None
close_price = float(index['f18']) if index['f18'] != '-' else None
volume_ratio = index['f10'] if index['f10'] != '-' else None
turnover_rate = float(index['f8']) if index['f8'] != '-' else None
pe_ratio = index['f9'] if index['f9'] != '-' else None
pb_ratio = index['f23'] if index['f23'] != '-' else None
stock_dict = {
"代码": index["f12"],
"名称": index['f14'],
"最新价": latest_price,
"涨跌幅": change_rate,
"涨跌额": change_amount,
"成交量(手)": volume,
"成交额": amount,
"振幅(%)": amplitude,
"最高": highest,
"最低": lowest,
"今开": open_price,
"昨收": close_price,
"量比": volume_ratio,
"换手率": turnover_rate,
"市盈率(动态)": pe_ratio,
"市净率": pb_ratio,
}
stocks.append(stock_dict)
# 将数据插入数据库
c.execute(
"INSERT INTO stocks (code, name, latest_price, change_rate, change_amount, volume, amount, amplitude, highest, lowest, open, close, volume_ratio, turnover_rate, pe_ratio, pb_ratio) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
(index["f12"], index['f14'], latest_price, change_rate, change_amount, volume, amount, amplitude,
highest, lowest, open_price, close_price, volume_ratio, turnover_rate, pe_ratio, pb_ratio))
conn.commit()
else:
break
# 关闭数据库连接
conn.close()
print("所有股票数据已保存到数据库!")
图片展示
打印结果
数据库结果
2. 作业心得
通过爬取股票信息,我更加熟悉了网络数据的获取和处理过程。在分析网页结构和API请求时,我掌握了如何有效提取和存储数据。这不仅增强了我的编程能力,还让我对金融数据的实时更新有了更深的理解。
作业③:中国大学2021主榜爬取
1. 作业代码与实现步骤
最后,我们将爬取中国大学2021主榜的所有院校信息,并将其存储到数据库中。
Gitee文件夹链接:https://gitee.com/nongchenc/crawl_project/blob/master/作业2/2.3.py
步骤详解
-
访问目标网站:前往 中国大学2021主榜。
-
检查网页结构:使用F12打开开发者工具,分析表格结构。
-
循环遍历提取:使用BeautifulSoup提取排名、学校名称、所在城市、类型和总分。
-
存储数据:将提取的数据保存到MySQL数据库中。
代码示例
def printUnivList(ulist, html, num):
data = json.loads(html) # 对数据进行解码
# 提取 数据 rankings 包含的内容
content = data['data']['rankings']
# 把学校的相关信息放到 ulist 里面
for i in range(num):
index = content[i]['rankOverall'] # 排名
name = content[i]['univNameCn'] # 学校名称
province = content[i]['province'] # 省市
score = content[i]['score'] # 总分
category = content[i]['univCategory'] # 类型
ulist.append([index, name, province, score, category])
# 将数据插入数据库
c.execute("INSERT INTO university_ranking (`rank`, name, province, score, category) VALUES (%s, %s, %s, %s, %s)",
(index, name, province, score, category))
conn.commit()
# 打印前 num 名的大学
tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}\t{4:^10}\t{5:^10}" # {1:{3}^10} 中的 {3} 代表取第三个参数
print(tplt.format("排名", "学校名称", "省市", chr(12288), "总分", "类型")) # chr(12288) 代表中文空格
for i in range(num):
u = ulist[i]
print(tplt.format(u[0], u[1], u[2], chr(12288), u[3], u[4])) # chr(12288) 代表中文空格
def main():
uinfo = []
url = 'https://www.shanghairanking.cn/api/pub/v1/bcur?bcur_type=11&year=2020'
html = getHTMLText(url) # 获取大学排名内容
printUnivList(uinfo, html, 30) # 输出排名前30的大学内容
main()
# 关闭数据库连接
conn.close()
图片展示
打印结果
数据库结果
2. 作业心得
通过爬取中国大学的排名信息,我对数据的结构化处理有了更深入的理解。整个过程让我认识到数据获取和整理的重要性,并掌握了如何有效地将这些数据存储到数据库中。记录调试过程也让我对每一步的操作有了直观的了解,这为我后续的学习奠定了良好的基础。