第二次实践
作业①
要求:
在中国气象网(http://www.weather.com.cn)给定城市集的7日天气预报,并保存在数据库。
输出信息:
序号 | 地区 | 日期 | 天气信息 | 温度 |
---|---|---|---|---|
1 | 北京 | 7日(今天) | 晴间多云,北部山区有阵雨或雷阵雨转晴转多云 | 31℃/17℃ |
2 | 北京 | 8日(明天) | 多云转晴,北部地区有分散阵雨或雷阵雨转晴 | 34℃/20℃ |
3 | 北京 | 9日(后台) | 晴转多云 | 36℃/22℃ |
4 | 北京 | 10日(周六) | 阴转阵雨 | 30℃/19℃ |
5 | 北京 | 11日(周日) | 阵雨 | 27℃/18℃ |
6...... |
爬取中国气象网网页内容
观察网页url,得到规律:
url = "http://www.weather.com.cn/weather/" + self.cityCode[city] + ".shtml"
对每个url,用BeautifulSoup对爬取到的网页内容进行匹配,并将得到的数据存入数据库
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
self.db.insert(city,date,weather,temp)
except Exception as err:
print(err)
建立数据库,实现打开、关闭、插入、打印等方法
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("{:4}\t{:8}\t{:16}\t{:20}\t{:20}".format("序号", "地区", "日期", "天气信息", "温度"))
i=1
for row in rows:
print("{:4}\t{:8}\t{:16}\t{:20}\t{:20}".format(i,row[0], row[1], row[2], row[3]))
i+=1
运行结果:
Gitee地址:
作业一:
https://gitee.com/flyme10086/data-excavate/blob/master/作业2/weather.py
心得体会:
此实验进一步锻炼了我对BeautifulSoup库的理解和使用,通过此实验,我初步接触了数据库的建立和使用,学到了sqlite3库的使用。
作业②
要求:
用requests和BeautifulSoup库方法定向爬取股票相关信息。
候选网站:
东方财富网:http://quote.eastmoney.com/center/gridlist.html#hs_a_board
技巧
在谷歌浏览器中进入F12调试模式进行抓包,查找股票列表加载使用的url,并分析api返回的值,并根据所要求的参数可适当更改api的请求参数。根据URL可观察请求的参数f1、f2可获取不同的数值,根据情况可删减请求的参数。
参考链接:https://zhuanlan.zhihu.com/p/50099084
输出信息:
序号 | 股票代码 | 股票名称 | 最新报价 | 涨跌幅 | 涨跌额 | 成交量 | 成交额 | 振幅 | 最高 | 最低 | 今开 | 昨收 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 688093 | N世华 | 28.47 | 62.22% | 10.92 | 26.13万 | 7.6亿 | 22.34 | 32.0 | 28.08 | 30.2 | 17.55 |
2...... |
爬取东方财富网沪深A股内容
通过抓包,得到沪深A股对应的url
url="http://6.push2.eastmoney.com/api/qt/clist/get?cb=jQuery112408105779319969169_1634089326282&pn=1&pz=20&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&fid=f3&fs=m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23&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&_=1634089326289"
对url中爬取到的数据进行分析,运用正则表达式进行匹配:
股票代码
re.findall(r'"f12":"(.*?)",',html)
股票名称
re.findall(r'"f14":"(.*?)",',html)
类似的,我们可以得到"最新报价","涨跌幅","涨跌额","成交量","成交额","振幅","最高","最低","今开","昨收"等数据,将数据插入数据库中
self.db.insert(ID[i], name[i], price[i], RFextent[i], RFquota[i], num[i], quota[i], extent[i], high[i], low[i], today[i], yesterday[i])
使用与第一题近似的代码建立数据库,实现打开、关闭、插入、打印等方法
class StockDB:
#打开数据库的方法
def openDB(self):
self.con=sqlite3.connect("stocks.db")
self.cursor=self.con.cursor()
try:
self.cursor.execute("create table stocks (sID varchar(16),sName varchar(64),sPrice varchar(16),sRFExtent varchar(16),sRFQuota varchar(16),sNum varchar(16),sQuota varchar(16),sExtent varchar(16),sHigh varchar(16),sLow varchar(16),sToday varchar(16),sYesterday varchar(16),constraint pk_stock primary key (sID,sName))")
except:
self.cursor.execute("delete from stocks")
#关闭数据库的方法
def closeDB(self):
self.con.commit()
self.con.close()
#插入数据的方法
def insert(self, ID, name, price, RFextent, RFquota, num, quota, extent, high, low, today, yesterday):
try:
self.cursor.execute("insert into stocks (sID,sName,sPrice,sRFExtent,sRFQuota,sNum,sQuota,sExtent,sHigh,sLow,sToday,sYesterday) values (?,?,?,?,?,?,?,?,?,?,?,?)",(ID, name, price, RFextent, RFquota, num, quota, extent, high, low, today, yesterday))
except Exception as err:
print(err)
#打印数据库内容的方法
def show(self):
self.cursor.execute("select * from stocks")
rows = self.cursor.fetchall()
print("{:4}\t{:8}\t{:16}\t{:8}\t{:8}\t{:8}\t{:8}\t{:16}\t{:8}\t{:8}\t{:8}\t{:8}\t{:8}".format("序号","股票代码","股票名称","最新报价","涨跌幅","涨跌额","成交量","成交额","振幅","最高","最低","今开","昨收", chr(12288)))
i=1
for row in rows:
print("{:4}\t{:8}\t{:16}\t{:8}\t{:8}\t{:8}\t{:8}\t{:16}\t{:8}\t{:8}\t{:8}\t{:8}\t{:8}".format(i,row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], chr(12288)))
i+=1
运行结果:
Gitee地址:
作业二:
https://gitee.com/flyme10086/data-excavate/blob/master/作业2/stock.py
心得体会:
本次作业与之前几次不同的地方在于:东方财富网的行情中心页面包含了所有股票信息。在左侧的菜单栏中包含了沪深个股、沪深指数等所有股票数据。每个板块的股票数据被隐藏在不同的菜单里。导致我们无法直接通过网页的url爬取所有数据,而使用f12进行抓包分析得到数据对应的url就能实现爬取操作。通过此次实验,我对f12的使用有了进一步了解。
作业③
要求:
爬取中国大学2021主榜(https://www.shanghairanking.cn/rankings/bcur/2021 )所有院校信息,并存储在数据库中,同时将浏览器F12调试分析的过程录制Gif加入至博客中。
技巧
分析该网站的发包情况,分析获取数据的api
输出信息:
排名 | 学校 | 总分 |
---|---|---|
1 | 清华大学 | 969.2 |
爬取所有院校信息
网页使用js,导致我们通过网页url只能爬取到第一页20个院校的数据,无法获得所有数据。因此使用f12进行抓包(抓包操作如下)后,获得js地址
url = "https://www.shanghairanking.cn/_nuxt/static/1632381606/rankings/bcur/2021/payload.js"
抓包示例:
对抓包得到的数据进行分析,使用正则表达式匹配学校名称和分数
name = re.findall(r'univNameCn:"(.*?)"', html)
score = re.findall(r'score:(.*?),', html)
将匹配获得的数据插入数据库
self.db.insert(i+1,name[i],score[i])
使用与第一、二题近似的代码建立数据库,实现打开、关闭、插入、打印等方法
class SchoolDB:
#打开数据库的方法
def openDB(self):
self.con=sqlite3.connect("schools.db")
self.cursor=self.con.cursor()
try:
self.cursor.execute("create table schools(sTop varchar(16),sName varchar(64),sScore varchar(16),constraint pk_school primary key (sName))")
except:
self.cursor.execute("delete from schools")
#关闭数据库的方法
def closeDB(self):
self.con.commit()
self.con.close()
#插入数据的方法
def insert(self, top, name, score):
try:
self.cursor.execute("insert into schools (sTop,sName,sScore) values (?,?,?)",(top, name, score))
except Exception as err:
print(err)
#打印数据库内容的方法
def show(self):
self.cursor.execute("select * from schools")
rows = self.cursor.fetchall()
print('{x:^{y}s}\t'.format(x="排名", y=10 - len("排名".encode('GBK')) + len("排名")), end='')
print('{x:^{y}s}\t'.format(x="学校", y=18 - len("学校".encode('GBK')) + len("学校")), end='')
print('{x:^{y}s}\t'.format(x="总分", y=6 - len("总分".encode('GBK')) + len("总分")))
for row in rows:
print('{x:^{y}s}\t'.format(x=row[0],y=10 - len(row[0].encode('GBK')) +len(row[0])), end='')
print('{x:^{y}s}\t'.format(x=row[1],y=20 - len(row[1].encode('GBK')) +len(row[1])), end='')
print('{x:^{y}s}\t'.format(x=row[2],y=6 - len(row[2].encode('GBK')) + len(row[2])))
运行结果:
(中间部分省略)
Gitee地址:
作业三:
https://gitee.com/flyme10086/data-excavate/blob/master/作业2/school.py