数据采集作业二

作业①

1)实验要求

  • 在中国气象网(http://www.weather.com.cn)给定城市集的7日天气预报,并保存在数据库
  • 输出信息
序号
区 
日期
天气信息
 
温度
1
7日(今
天) 
晴间多云,北部山区有阵雨或雷阵雨转
晴转多云
31℃/17℃ 
2
8日(明
天) 
多云转晴,北部地区有分散阵雨或雷阵
雨转晴 
34℃/20℃ 
3
9日(后
台) 
...  
4        
...        

2)思路分析

这个实验是书本实验的复现

主要有三个要点

(1)通过城市代码切换url,获取html

(2)7天的天气预报元素中,每天是一个li元素,7天的li结构是一样的,可以通过BeautifulSoup的元素查找方法来获取各个元素的值

(3)保存到数据库中

直接看代码

#031904131 车瑜莹
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()
        i=1
        print("{:4}\t{:10}\t{:14}\t{:24}\t{:16}".format("序号","城市", "日期", "天气信息", "温度"))
        for row in rows:
            print("{:4}\t{:10}\t{:10}\t{:24}\t{:16}".format(i,row[0], row[1], row[2], row[3]))
            i+=1
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") #找到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)
        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")

得到结果

 3)心得体会

初步了解到了sqlite3的用法,但是还不太熟练,如何利用城市代码切换url也还要多练习

 

 

作业

1)实验要求

  • 用requests和自选提取信息方法定向爬取股票相关信息,并存储在数据库中
  • 候选网站:东方财富网:https://www.eastmoney.com/
                      新浪股票:http://finance.sina.com.cn/stock/
  • 技巧:在谷歌浏览器中进入F12调试模式进行抓包,查找股票列表加载使用的url,并分析api返回的值,并根据所要求的参数可适当更改api的请求参数。根据URL可观察请求的参数f1、f2可获取不同的数值,根据情况可删减请求的参数。
    参考链接:https://zhuanlan.zhihu.com/p/50099084
  • 输出信息
序号 
股票代
码 
最新
报价 
涨跌幅
涨跌
额 
成交
量 
额 
振幅 
最低 
 
开 
昨收 
1
688093 
N
62.22%
10.92 
...              
...                        

2)思路分析

先对网页进行分析,过滤js文件

 

 

 

 

 

 

 建立数据库

#数据库部分参照第一题进行修改
class NumberDB:
    # 打开数据库的方法
    def openDB(self):
        self.con = sqlite3.connect("numbers.db")
        self.cursor = self.con.cursor()
        try:
            self.cursor.execute(
                "create table numbers (nNumber varchar(16),nName varchar(64),nNew varchar(16),nRisefall varchar(16),nRisefallnumber varchar(16),nTrading varchar(16),nTradingnumber varchar(16),nRise varchar(16),nHighest varchar(16),nLowest varchar(16),nToday varchar(16),nYestoday varchar(16),constraint pk_number primary key(nNumber,nName))")
        except:
            self.cursor.execute("delete from numbers")

获取数据

def getHTML(url,headers):
    try:
        r = requests.get(url, timeout=30, headers=headers)
        jsons = r.text[41:][:-2]  # 将前后用不着的字符排除
        text_json = json.loads(jsons)
        return text_json  # 返回json值
    except:
        return ""

将获取的数据插入数据库

class NumberForecast:
    def __init__(self):
        self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36 Edg/94.0.992.47'}

    def GetHTML(self):
        url="http://49.push2.eastmoney.com/api/qt/clist/get?cb=jQuery11240918880626239239_1602070531441&pn=1&pz=20&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&fid=f3&fs=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&_=1602070531442"
        result = getHTML(url,self.headers)
        self.db = NumberDB()
        self.db.openDB()
        for f in result['data']['diff']:
            self.db.insert(f['f12'], f['f14'], f['f2'], f['f3'], f['f4'], f['f5'], f['f6'], f['f7'], f['f15'], f['f16'],f['f17'],f['f18'])
        self.db.show()
        self.db.closeDB()

得到结果

 3)心得体会

这次尝试使用了json来爬取数据,同时将第一题的数据库稍加改造运用到了第二题,让我对sqlite3的掌握也更加熟练了一点

 

作业③

1)实验要求

  • 爬取中国大学2021主榜(https://www.shanghairanking.cn/rankings/bcur/2021)所有院校信息,并存储在数据库中,同时将浏览器F12调试分析的过程录制Gif加入至博客中。
  • 技巧:分析该网站的发包情况,分析获取数据的api 
  • 输出信息
排名 学校 总分
1 清华大学
969.2 

2)思路分析

对网页进行F12调试分析

 

抓包的过程与第二题相同

 

 建立数据库

class SchoolDB:
    # 打开数据库的方法
    def openDB(self):
        self.con = sqlite3.connect("schools.db")
        self.cursor = self.con.cursor()
        try:
            self.cursor.execute(
                "create table schools (cSchool varchar(64),cNumber varchar(16),constraint pk_stock primary key (cSchool,cNumber))")
        except:
            self.cursor.execute("delete from schools")

获取数据

def getHTML(url,headers):
    try:
        r = requests.get(url,headers=headers, timeout=30)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return ""

将需要的数据插入数据库

    def GetHTML(self):
        url="https://www.shanghairanking.cn/_nuxt/static/1632381606/rankings/bcur/2021/payload.js"
        data = getHTML(url, self.headers)
        # print(data)

        self.db = SchoolDB()
        self.db.openDB()
        #学校
        school = re.findall(r'univNameCn:"(.*?)"', data)
        #总分
        number = re.findall(r'score:(.*?),', data)
        for i in range(len(school)):
            self.db.insert(school[i],number[i])
        self.db.show()
        self.db.closeDB()

得到结果

 3)心得体会

这道题和第二题非常类似,是对 sqlite3和正则的进一步掌握

 

 

实验代码:

moocy: 是cyy的代码呀 - Gitee.com

posted @ 2021-10-15 01:45  车车别吃了  阅读(82)  评论(0编辑  收藏  举报