• 微信公众号:美女很有趣。 工作之余,放松一下,关注即送10G+美女照片!

数据采集第二次作业

开发技术 开发技术 3小时前 2次浏览

作业①

(1)实验要求:

  • 输出信息:
序号 地区 日期 天气信息 温度
1 北京 7日(今天) 晴间多云,北部山区有阵雨或雷阵雨转晴转多云 31℃/17℃
2 北京 8日(明天) 多云转晴,北部地区有分散阵雨或雷阵雨转晴 34℃/20℃
3 北京 9日(后台) 晴转多云 36℃/22℃
4 北京 10日(周六) 阴转阵雨 30℃/19℃
5 北京 11日(周日) 阵雨 27℃/18℃
6……

 

 

 

 (2)题目分析:

通过查看不同城市的七日天气的URL可知,不同城市有不同的城市编码:

北京:http://www.weather.com.cn/weather1d/101010100.shtml

上海:http://www.weather.com.cn/weather1d/101020100.shtml

广州:http://www.weather.com.cn/weather1d/101280101.shtml于是我们可以定义url为:

self.cityCode = {"北京": "101010100", "上海": "101020100", "广州": "101280101", "深圳": "101280601"}
url = "http://www.weather.com.cn/weather/" + self.cityCode[city] + ".shtml"

我们需要的信息为地区、日期、天气信息,于是通过下面方式来获得:

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  #获取天气

定义一个函数 forecastCity 来获得所需内容

 1     def forecastCity(self, city):
 2         if city not in self.cityCode.keys():
 3             print(city + " code cannot be found")
 4             return
 5 
 6         url = "http://www.weather.com.cn/weather/" + self.cityCode[city] + ".shtml"
 7         try:
 8             req = urllib.request.Request(url, headers=self.headers)
 9             data = urllib.request.urlopen(req)
10             data = data.read()
11             dammit = UnicodeDammit(data, ["utf-8", "gbk"])
12             data = dammit.unicode_markup
13             soup = BeautifulSoup(data, "lxml")
14             lis = soup.select("ul[class='t clearfix'] li")
15             for li in lis:
16                 try:
17                     date = li.select('h1')[0].text   #获取日期
18                     weather = li.select('p[class="wea"]')[0].text  #获取天气
19                     temp = li.select('p[class="tem"] span')[0].text + "/" + li.select('p[class="tem"] i')[0].text  #获取天气
20                     print(city, date, weather, temp)
21                     self.db.insert(city, date, weather, temp)
22                 except Exception as err:
23                     print(err)
24         except Exception as err:
25             print(err)

定义一个类,来将数据存储到数据库中:

 1 class WeatherDB:
 2     def openDB(self):
 3         self.con=sqlite3.connect("weathers.db")
 4         self.cursor=self.con.cursor()
 5         try:
 6             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))")
 7         except:
 8             self.cursor.execute("delete from weathers")
 9     def closeDB(self):
10         self.con.commit()
11         self.con.close()
12 
13     def insert(self, city, date, weather, temp):
14         try:
15             self.cursor.execute("insert into weathers (wCity,wDate,wWeather,wTemp) values (?,?,?,?)",(city, date, weather, temp))
16         except Exception as err:
17             print(err)
18 
19     def show(self):
20         self.cursor.execute("select * from weathers")
21         rows = self.cursor.fetchall()
22         print("%-16s%-16s%-32s%-16s" % ("city", "date", "weather", "temp"))
23         for row in rows:
24             print("%-16s%-16s%-32s%-16s" % (row[0], row[1], row[2], row[3]))

结果展示:(控制台输出)

数据采集第二次作业

数据库查看:

数据采集第二次作业

 码云地址:

(3)心得体会:

实验一主要是一个复现的题目,听了老师的讲解,对requests和Beautifulsoup的使用更加熟练,另外本次实验有新加了对存储数据的练习,对数据库也有了新的认识。

 

作业②

(1)实验要求:

  • 要求:用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……        

 

 

 

(2)题目分析:

首先解析网页,通过F12键,进行抓包分析,过滤出js文件,找到股票数据的URL

数据采集第二次作业

然后通过查看headers可以获得URL,i来控制选择的个股:

"沪深A股":"fs=m:0+t:6,m:0+t:13,m:0+t:80,m:1+t:2,m:1+t:23", "上证A股":"fs=m:1+t:2,m:1+t:23"
url = "http://25.push2.eastmoney.com/api/qt/clist/get?cb=jQuery112409657064113470295_1634193335681&pn=" +str(i)+ "&pz=20&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&fid=f3&"+ str(fs) +"&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&_=1634193335682"

 股票的信息存在如下图所示位置:

数据采集第二次作业

定义正则表达式来爬取数据:

reg = '"diff":[(.*?)]'  #定义正则表达式,爬取数据

我们随便选择一个个股,就可以看到我们所需的各个信息存放的位置是在哪里:

数据采集第二次作业

 

例如股票名字在f14中,所以可以通过下面的表达式提取:(其余信息同理)

Stock_name = list[0][14].split(":")[-1].replace(""", "") #把引号替换为空字符串,这里要转义

 最后将所有的数据存储到数据库当中:

class StocksDB:
    #打开数据库的方法
    def openDB(self):
        self.con=sqlite3.connect("stocks.db")
        self.cursor=self.con.cursor()
        try:
            self.cursor.execute("create table stocks (sStock_code varchar(16),sStock_name varchar(64),sStock_price varchar(16),sPrice_limit varchar(16),sPrice_num varchar(16),sTurn_num varchar(16),sTurn_price varchar(16),sSwing varchar(16),sHighest varchar(16),sLowest varchar(16),sToday varchar(16),sYesterday varchar(16),constraint pk_stock primary key (sStock_code,sStock_num))")
        except:
            self.cursor.execute("delete from stocks")
    #关闭数据库的方法
    def closeDB(self):
        self.con.commit()
        self.con.close()
    #插入数据的方法
    def insert(self, Stock_code, Stock_name, Stock_price, Price_limit, Price_num, Turn_num, Turn_price, Swing, Highest, Lowest, Today, Yesterday):
        try:
            self.cursor.execute("insert into stocks (sStock_code,sStock_name,sStock_price,sPrice_limit,sPrice_num,sTurn_num,sTurn_price,sSwing,sHighest,sLowest,sToday,sYesterday) values (?,?,?,?,?,?,?,?,?,?,?,?)",(Stock_code, Stock_name, Stock_price, Price_limit, Price_num, Turn_num, Turn_price, Swing, Highest, Lowest, 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

结果展示:(控制台输出)

数据采集第二次作业

 

数据库查看:

 数据采集第二次作业

 

码云地址:

(3)心得体会:

在第一题的基础上,第二题加了F12调试模式进行抓包,第一次进行操作有些不熟练,花费了很多的时间,后续还要多加练习。

 

 

作业③

 (1)实验要求:

 

    • 要求: 爬取中国大学2021主榜 https://www.shanghairanking.cn/rankings/bcur/2021
      所有院校信息,并存储在数据库中,同时将浏览器F12调试分析的过程录制Gif加入至博客中。

    • 技巧: 分析该网站的发包情况,分析获取数据的api

    • 输出信息:

      排名 学校 总分
      1 清华大学 969.2

       

 

 

 

(2)题目分析:

首先就是要通过抓包获取url信息,具体操作与实验二相同,见下图演示:

数据采集第二次作业

获得的url为:

url='https://www.shanghairanking.cn/_nuxt/static/1632381606/rankings/bcur/2021/payload.js'

然后定义正则表达式来获取学校名字以及学习分数:

1 r = requests.get(url,headers=self.headers )
2 r.raise_for_status()  # 用来产生异常信息
3 r.encoding = r.apparent_encoding  # 用来修改它的编码
4 data=r.text
5 name = re.findall(r'univNameCn:"(.*?)"', data)
6 score = re.findall(r'score:(.*?),', data)

定义一个输出格式,将数据输出,并且存入数据库:

1  t_plt = "{0:^10}t{1:{3}^12}t{2:^15}"
2  print(t_plt.format("排名", "学校名称", "总分", chr(12288)))
3  for i in range (len(score)):
4         try:
5             print(t_plt.format(i+1,name[i],score[i],chr(12288)))
6             self.db.insert(name[i],score[i])
7          except:
8              return ""

最后将爬取到的数据存储到数据库中:

 1 class RankDB:
 2     def openDB(self):
 3         self.con=sqlite3.connect("ranks.db")
 4         self.cursor=self.con.cursor()
 5         try:
 6             self.cursor.execute("create table ranks (wName varchar(16),wSore varchar(16),constraint pk_rank primary key (wName,wSore))")
 7         except:
 8             self.cursor.execute("delete from ranks")
 9     def closeDB(self):
10         self.con.commit()
11         self.con.close()
12 
13     def insert(self, name,sore):
14         try:
15             self.cursor.execute("insert into ranks (wName,wSore) values (?,?)",(name,sore))
16         except Exception as err:
17             print(err)
18 
19     def show(self):
20         self.cursor.execute("select * from ranks")
21         rows = self.cursor.fetchall()
22         print("%-16s%-16s" % ("name", "sore"))
23         for row in rows:
24             print("%-16s%-16s" % (row[0], row[1]))

结果展示:(控制台输出)

 数据采集第二次作业  数据采集第二次作业

 

 数据库中查看:

数据采集第二次作业

 

 码云地址:

(3)心得体会:

实验三是对实验一和实验二的总结与巩固,通过以上实验我能够正确分析网站的发包情况,这样就可以不用再去找翻页规律了,比较方便。

 

 

 

 

 

 

 


程序员灯塔
转载请注明原文链接:数据采集第二次作业
喜欢 (0)