第二次作业
-
作业1:
要求:在中国气象网给定城市集的7日天气预报,并保存在数据库。
作业一代码文件夹:作业一
代码显示如下
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={"北京":"101010100","上海":"101020100","广州":"101280101","深圳":"101280601"}
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")
保存在数据库,本文采用Navicat进行数据库可视化

-
心得体会
对于本次实验,学习到的是如何利用bs4库将数据从网站中爬取后,利用sqlite3的数据库将数据持久化。
这次实验是复现书本上的例题,让我对bs4库有了清晰的认识,也懂得如何使用bs库和数据存储。
-
作业2:
要求:用requests和BeautifulSoup库方法定向爬取股票相关信息,并存储在数据库中。
作业二代码文件夹:作业二
代码显示如下
import requests
import json
from fake_useragent import UserAgent
import pandas as pd
from sqlalchemy import create_engine
import mysql.connector
def web_page(n):
url = f"http://16.push2.eastmoney.com/api/qt/clist/get?cb=jQuery112408936794087215907_1696658940293&pn={n}&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&_=1696658940294"
urll = 'https://98.push2.eastmoney.com/api/qt/clist/get?cb=jQuery1124029546986442297585_1696746433261&pn=1&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&_=1696746433262'
headers = {
'User-Agent':UserAgent().chrome
}
'''
序号,股票代码:f12,股票名称:f14,最新报价:f2,涨跌幅:f3,涨跌额:f4,成交量:f5,成交额:f6
振幅:f7,最高:f15,最低:f16,今开:f17,昨收:f18
f12,f14,f2,f3,f4,f5,f6,f7,f15,f16,f17,f18
'''
res = requests.get(url=url,headers=headers)
res.encoding = res.apparent_encoding
# print(type(res.text),res.text)
# 提取括号内的JSON数据部分
start_index = res.text.find('(') + 1
end_index = res.text.rfind(')')
json_data = res.text[start_index:end_index]
# 解析JSON数据
# print(json_data)
# print(type(json_data))
json_obj = json.loads(json_data)
# 打印输出
# print(type(json_obj))
# print(json_obj)
#取出data中的数据列表list
data = json_obj['data']['diff']
# print(data,type(data))
global goods_list
name = ['f12','f14','f2','f3','f4','f5','f6','f7','f15','f16','f17','f18']
global count
for li in data:
list =[]
list.append(count)
for n in name:
list.append(li[n])
count += 1
goods_list.append(list)
# print(goods_list)
# print(len(goods_list))
# def get_disdinct():
# url = "https://quote.eastmoney.com/center/api/sidemenu.json"
# headers = {
# 'User-Agent':UserAgent().chrome
# }
# res = requests.get(url=url,headers=headers)
# res.encoding = res.apparent_encoding
# json_data = json.loads(res.text)
# # print(json_data)
# # print(type(json_data))
# # print(len(json_data))
# for msg in json_data:
# print(msg)
if __name__ == "__main__":
n = int(input("请输入需要下载几页股票信息?"))
goods_list = []
count = 1
for i in range(n):
web_page(i+1)
df = pd.DataFrame(data=goods_list,columns=['序号','股票代码','股票名称','最新报价','涨跌幅','涨跌额','成交量','成交额','振幅','最高','最低','今开','昨收'])
df.set_index('序号')
# print(df)
engine = create_engine("mysql+mysqlconnector://root:123456@127.0.0.1:3306/homework1")
df.to_sql("stock",engine,if_exists="replace",index=False)
保存在mysql数据库,本文采用Navicat进行数据库可视化

-
心得体会
本次实验是爬取东方财富网,在谷歌浏览器中进入F12调试模式进行抓包,查找股票列表加载使用的url,并分析api返回的值,并根据所要求的参数可适当更改api的请求参数。根 据URL可观察请求的参数f1、f2可获取不同的数值,根据情况可删减请求的参数。
下图是F12进行抓包的过程,在开发者工具中,查找页面元素,寻找页面数据是从哪个网页中传递过来的。

寻找到该数据传递的网页之后,查看页面数据,发现是json数据的格式

于是学习了如何访问数据后,将其json格式的数据转化为python的字典,json.loads函数就起到了这个作用,同时要保证loads()函数中传递的参数需要是json格式数据,但是这个网页中并不是完整的json格式,所以参考代码中的字符串find函数,将不需要的部分,即不是json格式的部分去除,只需要自己想要的json数据即可。
本次作业需要将数据存储进数据库,本文采用了pandas中的to_sql。但是使用这个函数需要同时下载sqlalchemy库,和mysql-connector-python库
# 分别复制下列的代码进终端运行即可下载
pip install sqlalchemy
pip install mysql-connector-python
作业二让我学会了如何将下载的数据连接数据库,并将数据传入数据库
-
作业3:
要求:爬取中国大学2021主榜所有院校信息,并存储在数据库中,同时将浏览器F12调试分析的过程录制Gif加入至博客中。
作业三代码文件夹:作业三
代码显示如下:
import requests
from fake_useragent import UserAgent
import re
import pandas as pd
from sqlalchemy import create_engine
import mysql.connector
url = 'https://www.shanghairanking.cn/_nuxt/static/1695811954/rankings/bcur/2021/payload.js'
headers = {
'User-Agent':UserAgent().chrome
}
res = requests.get(url=url,headers=headers)
res.encoding = res.apparent_encoding
# print(type(res.text))
# print(res.text)
start_index = res.text.find("o")+3
end_index = res.text.find(")")
function_list_key= res.text[start_index:end_index].split(',')
# print(function_list)
start_index_1 = res.text.rfind("}")+1
end_index_1 = res.text.rfind(")")-2
function_list_value = res.text[start_index_1:end_index_1].split(",")
# print(function_list_value)
mapper = dict(zip(function_list_key,function_list_value))
# print(mapper)
name = re.findall(r'univNameCn:"(.*?)",',res.text)
# print(len(name))
score = re.findall(r',score:(.*?),',res.text)
# print(len(score))
# print(score)
# print(name)
province_new = []
province = re.findall(r'province:(.*?),',res.text)
# print(len(province),province)
for item in province:
province_new.append(mapper[item])
# print(province_new,len(province_new))
category_new = []
category = re.findall(r'univCategory:(.*?),',res.text)
# print(len(category),category)
for item in category:
category_new.append(mapper[item])
# print(category_new,len(category_new))
df = pd.DataFrame(columns=['排名','学校','省市','类型','总分'])
num = [i+1 for i in range(582)]
nnum = pd.Series(num)
sname = pd.Series(name)
sscore = pd.Series(score)
df['排名']= nnum
df['学校']=sname
df['总分']=sscore
df['省市']= province_new
df['类型']= category_new
# df.to_excel("123.xlsx")
engine = create_engine("mysql+mysqlconnector://root:123456@127.0.0.1:3306/homework1")
df.to_sql('school',engine,if_exists='replace',index=False)
保存在mysql数据库,本文采用Navicat进行数据库可视化

-
心得体会
对于本次这个网站,采用抓包的方式进行寻找页面中传递的数据,具体过程在如下gif图像

对于本次实验,有一个疑难点,刚开始认为该网页为json数据格式,故与第二题一样,利用json.loads进行转化,但是发现报错,查找报错后发现,网站不是json数据,对于每个key并不是字符串。
