2023数据采集与融合技术实践作业二
作业①
实验要求
要求:在中国气象网(http://www.weather.com.cn)给定城市集的7日天气预报,并保存在数据库。
输出信息:
Gitee文件夹链接
代码
from bs4 import BeautifulSoup
from bs4 import UnicodeDammit
import urllib.request
import sqlite3
class WeatherDB:
def openDB(self):
self.con=sqlite3.connect("weathers.db")
self.cursor=self.con.cursor()
try:
self.cursor.execute("create table weathers (wCity varchar(16),wDate varchar(16),wWeather varchar(64),wTemp varchar(32),constraint pk_weather primary key (wCity,wDate))")
except:
self.cursor.execute("delete from weathers")
def closeDB(self):
self.con.commit()
self.con.close()
def insert(self, city, date, weather, temp):
try:
self.cursor.execute("insert into weathers (wCity,wDate,wWeather,wTemp) values (?,?,?,?)",
(city, date, weather, temp))
except Exception as err:
print(err)
def show(self):
self.cursor.execute("select * from weathers")
rows = self.cursor.fetchall()
print("%-16s%-16s%-32s%-16s" % ("city", "date", "weather", "temp"))
for row in rows:
print("%-16s%-16s%-32s%-16s" % (row[0], row[1], row[2], row[3]))
class WeatherForecast:
def __init__(self):
self.headers = {
"User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.0 x64; en-US; rv:1.9pre) Gecko/2008072421 Minefield/3.0.2pre"}
self.cityCode = {"上海": "101020100", "广州": "101280101", "深圳": "101280601","闽侯":"101230103"}
def forecastCity(self, city):
if city not in self.cityCode.keys():
print(city + " code cannot be found")
return
url = "http://www.weather.com.cn/weather/" + self.cityCode[city] + ".shtml"
try:
req = urllib.request.Request(url, headers=self.headers)
data = urllib.request.urlopen(req)
data = data.read()
dammit = UnicodeDammit(data, ["utf-8", "gbk"])
data = dammit.unicode_markup
soup = BeautifulSoup(data, "lxml")
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=li.select('p[class="tem"] span')[0].text+"/"+li.select('p[class="tem"] i')[0].text
print(city,date,weather,temp)
self.db.insert(city,date,weather,temp)
except Exception as err:
print(err)
except Exception as err:
print(err)
def process(self, cities):
self.db = WeatherDB()
self.db.openDB()
for city in cities:
self.forecastCity(city)
# self.db.show()
self.db.closeDB()
ws = WeatherForecast()
ws.process([ "上海", "广州", "深圳","闽侯"])
print("completed")
运行结果
心得体会
书本上的代码,又仔细看了一遍,难度不是很大,做作业已经看懂过了。使用函数来做爬虫确实是非常简介美观的。
作业②
要求:用requests和BeautifulSoup库方法定向爬取股票相关信息,并存储在数据库中。
候选网站:东方财富网:https://www.eastmoney.com/
新浪股票:http://finance.sina.com.cn/stock/
技巧:在谷歌浏览器中进入F12调试模式进行抓包,查找股票列表加载使用的url,并分析api返回的值,并根据所要求的参数可适当更改api的请求参数。根据URL可观察请求的参数f1、f2可获取不同的数值,根据情况可删减请求的参数。
参考链接:https://zhuanlan.zhihu.com/p/50099084
输出信息:
Gitee文件夹链接
代码
import requests
import re
import pandas as pd
headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3775.400 QQBrowser/10.6.4209.400"}
def getHtml(page):
url = "http://32.push2.eastmoney.com/api/qt/clist/get?cb=jQuery1124013530104765925532_1696661861389&pn="+str(page)+"&pz=20&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&wbp2u=|0|0|0|web&fid=f3&fs=m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23,m:0+t:81+s:2048&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&_=1696661861390"
r = requests.get(url,headers=headers).text
# print(r)
pat0='"diff":\[\{.*?\}\]' # 找到信息
data=re.compile(pat0,re.S).findall(r)
return data
#print(data)
#爬取单页股票数据
def getOnePageStock(page):
data=getHtml(page)
datas=data[0].split('},{')
#print(datas)
stocks=[]
for i in range(len(datas)):
str1=r'"(\w)+":'
stock=re.sub(str1," ",datas[i])
stock =stock.split(",")
stocks.append(stock)
return stocks
page=1
stocks=getOnePageStock(page)
# print(stocks)
pages = int(input("请输入要爬的页数:"))
while page<=pages:
page+=1
stocks.extend(getOnePageStock(page))
df=pd.DataFrame(stocks)
# print(df)
# 把找的的不用的信息列删掉。
df.drop([0,7,8,9,10,12,18,19,20,21,22,23,24,25,26,27,28,29,30],axis=1,inplace=True)
#print(df)
df.index = range(1,len(df) + 1)
df=df[[11,13,1,2,3,4,5,6,14,15,16,17]] # 修改顺序
columns = {11:"股票代码",13:"股票名称",1:"最新报价",2:"涨跌幅",3:"涨跌额",4:"成交量",5:"成交额",6:"振幅",14:"最高",15:"最低",16:"今开",17:"昨收"}
df=df.rename(columns=columns)
print(df)
df.to_csv('股票.csv', encoding='utf-8-sig',index=False) # 保存为csv格式的文件
运行结果
心得体会
这这串代码里,使用抓包的方式得到了网页的数据,再利用正则提取出所有股票的信息,再得到所有的信息后,手动查看哪些是不需要的,最后用drop函数删掉不用的,再排序输出,保存到文件中,通过这个实验,我学会了根据不同的需求来抓不同的包,并且合理的利用正则表达式来得到所需要的数据,人工剔除不需要的数据,同时合理的观察网页结构和正确抓包也是极其重要的,极大的提高了我的爬虫水平。
作业③
要求:爬取中国大学2021主榜(https://www.shanghairanking.cn/rankings/bcur/2021)所有院校信息,并存储在数据库中,同时将浏览器F12调试分析的过程录制Gif加入至博客中。
技巧:分析该网站的发包情况,分析获取数据的api
抓包过程
代码
import re
import requests
import pandas as pd
result = pd.DataFrame()
headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3775.400 QQBrowser/10.6.4209.400"}
url = "https://www.shanghairanking.cn/_nuxt/static/1695811954/rankings/bcur/2021/payload.js"
html = requests.get(url,headers=headers)
r = html.text
# print(r)
pat_name = 'univNameCn:"(.*?)"' # 找到学校名
data_name = re.compile(pat_name, re.S).findall(r)
# print(data_name)
pat_score = 'score:(.*?),' # 找到学校分数
data_score = re.compile(pat_score, re.S).findall(r)
pat_prov = 'province:(.*?),' # 找到学校省份
data_prov = re.compile(pat_prov, re.S).findall(r)
pat_category = 'univCategory:(.*?),' # 找到学校类别
data_category = re.compile(pat_category, re.S).findall(r)
key = re.compile('function\((.*?)\)',re.S).findall(r)
key = key[0].split(',')
key.append("") # 不知道为什么key比value少了3个,手动加3个
key.append("")
key.append("")
# print(key)
value = re.compile(r'mutations:\[\]\}\}\((.*?)\)', re.S).findall(r)
value = value[0].split(',')
# print(len(value))
for i in range(0,897): # 把多出来的双引号去掉
value[i].replace('"','')
# Types[i] = dataDic[Types[i]].replace('"', '')
# print(value)
# print(len(value))
dic={}
for i in range(0,len(value)): # 把键值对放字典里
dic[key[i]]=value[i]
# print(dic)
for i in range(0,582):
data_category[i] = dic[data_category[i]].replace('"', '') # 字典映射
data_prov[i] = dic[data_prov[i]].replace('"', '')
df = pd.DataFrame({'排名':[i+1],'学校名称':[data_name[i]],'分数':[data_score[i]],'省份':[data_prov[i]],'类型':[data_category[i]]})
result = pd.concat([result, df])
print(result)
result.to_csv('大学.csv', encoding='utf-8-sig',index=False) # 保存为csv格式的文件
运行结果
心得体会
这个问题花了最多时间,很快就找到js文件,也用和第二题一样的函数搞出来了学校名和得分,但是这网站省份和学校类型是用的字母替代的,我完全没思路,搞了好久没搞出来,最后上网查才知道js文件的第一行和最后一行做成字典映射就能解决这个问题,才把这个问题解决。这个问题教会我一定要多认真看js文件,你出问题的地方可能就是你没注意的地方。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)