Fork me on GitHub

[数据采集]实验二

[数据采集]实验二


一、作业①


1 、作业内容

- 要求: 爬取在中国气象网给定城市集的7日天气预报,并保存在数据库中。

- 输出信息:

Gitee完整代码链接

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

2、实现过程

2.1主函数部分:

if __name__ == "__main__":
    ws = WeatherForecast()
    ws.process(["北京", "上海", "广州", "深圳"])
    print("completed")

2.2各部分代码:

2.2.1构造一个WeatherForecast类,用于解析指定城市的天气数据:

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, "html.parser")  # 解析网页
                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)

            print("------------输出数据库结果------------")
            self.db.show()
            self.db.closeDB()

2.2.2将解析出来的内容保存到数据库

代码如下:

class WeatherDB:
    def openDB(self):  # 和数据库进行连接
        self.con=sqlite3.connect("weathers.db")
        self.cursor=self.con.cursor()
        try:            # sql语句创建表weathers用于保存天气数据
            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:    # 编译执行sql语句将数据插入数据表
            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]))

2.3输出结果截图

  • 得到的数据:

  • 保存到数据库


二、作业②


1 、作业内容

- 要求:用requests和自选提取信息方法定向爬取东方财富网,得到股票相关信息,并存储在数据库中

- 输出信息:

Gitee完整代码链接

序号 股票代码 股票名称 最新报价 涨跌幅 涨跌额 成交额 最高 最低
1 688093 N世华 28.47 62.22% 10.92 7.6亿 32.0 28.08
2
... ...

2、实现过程

2.1解析网页

  • 第一次爬取的时候发现爬取下来的html页面并没有需要的数据,后来发现浏览器只是发起了javascript网络访问,然后将服务器返回的数据插入网页,无法通过网址直接获取对应页的的页面数据。

  • 之后根据老师的指导,通过F12键,进行抓包分析,过滤出js文件,找到了股票数据网页。

  • 接着点击Headers,Request URL内的网址就是我们需要的数据

  • 之后就可以按照常规操作进行下一步啦

2.2实现代码

2.2.1主函数部分
def main():
    html = getHtml("1")             # 爬取第一页的数据
    list = parsePage(html)          # 解析html页面得到所需数据
    printList(list)                 # 按格式打印出得到的数据
    dbpath = r'D:\作业2\shares.db'  # 数据库路径
    saveData2DB(list, dbpath)       # 将数据保存到数据库
2.2.2部分主要代码
  • 通过F12得到的数据所在url为
url = "https://9.push2.eastmoney.com/api/qt/clist/get?cb=jQuery1124025500369212952667_1634094365855&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&_=1634094365856"
  • 用urllib.request方法访问服务器
  • 并且url中有"pn=1",可更改其数值进行换页
def getHtml(page):
    url = "https://9.push2.eastmoney.com/api/qt/clist/get?cb=jQuery1124025500369212952667_1634094365855&pn="+page+"&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&_=1634094365856"
    req = urllib.request.Request(url, headers=headers)
    html=urllib.request.urlopen(req)
    html=html.read()
    dammit=UnicodeDammit(html,["utf-8","gbk"])  # 编码
    html=dammit.unicode_markup
    return html                                  #得到页面数据
  • 对数据库进行初始化
def init_db(dbpath):
        sql = '''          #sql语句创建数据表shares用于存放数据
            create table shares
            (
            id text,
            name text,
            price text,
            changeRate text,
            change text,
            currentPrice text,
            max text,
            min text
            );
        '''
        conn = sqlite3.connect(dbpath)  #连接指定的数据库
        cursor = conn.cursor()
        cursor.execute(sql)              #执行sql语句
        conn.commit()                    
        conn.close()                    #关闭数据库连接
  • 将数据保存到数据库
def saveData2DB(datalist, dbpath):
    init_db(dbpath)                # 初始化数据库
    conn = sqlite3.connect(dbpath) # 连接到数据库
    cur = conn.cursor()
    for data in datalist:          # 将数据逐条存入数据表
        for index in range(len(data)):
            data[index] = '"' + data[index] + '"'
            sql = '''
                insert into shares(
                    id,name,price,changeRate,change,currentPrice,max,min
                    )
                    values(%s)
            ''' % ",".join(data)
        cur.execute(sql)            # 执行sql语句插入数据
        conn.commit()
    cur.close()
    conn.close()
    print("保存到数据库成功!")

2.3结果截图

  • 输出数据:

  • 保存到数据库:


三、作业③


1 、作业内容

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

- 输出信息:

Gitee完整代码链接

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

2、实现过程

2.1解析网页

  • 这次爬取的html页面内容就包含了需要的信息,直接分析提取
  • 查看网页源代码,发现每一条排名都在一个tr标签内
  • 每一个tr标签下有许多td标签,分别存放这条排名中的不同数据,例如排名在第一个td标签中
  • 接下来就可以开始下一步

2.2实现代码

2.2.1主函数部分
def main():
    html = getHtml()              # 爬取指定页面
    list = parsePage(html)        # 解析html页面数据
    printList(list)               # 按格式打印页面数据
    dbpath = r'D:\作业2\rank.db'  # 数据库路径
    saveData2DB(list, dbpath)     # 数据保存到数据库
2.2.2部分主要代码
  • 解析html页面数据
def parsePage(html):
    datas = []                    # 用于记录得到的数据
    soup = BeautifulSoup(html, 'html.parser')
    lis = soup.find_all("tr")     # 先找到所有tr标签
    for i in range(1,len(lis)):   # 再找每个tr内的td标签
        try:
            tr=lis[i]
            td=tr.find_all("td")
            rank=td[0].find('div').text.strip()     # 学校排名
            name=td[1].find('a').text.strip()       # 学校名称
            score=td[4].text.strip()                # 总分
            datas.append([rank,name,score])
        except Exception as err:
            print(err)
    return datas
  • 将数据保存到数据库
def saveData2DB(datalist, dbpath):
    init_db(dbpath)                    # 初始化数据库
    conn = sqlite3.connect(dbpath)     # 连接数据库
    cur = conn.cursor()
    for data in datalist:
        for index in range(len(data)):
            data[index] = '"' + data[index] + '"'
            sql = '''
                insert into rank(      # sql语句逐条插入数据
                    id,name,score
                    )
                    values(%s)
            ''' % ",".join(data)
        cur.execute(sql)
        conn.commit()
    cur.close()
    conn.close()
    print("保存到数据库成功!")

2.3结果截图

  • 输出数据:

  • 保存到数据库:

心得体会

1.首次接触到将爬取到的数据保存到数据库
2.有时可能数据没有存放在我们爬取到的html页面中,需要进一步使用F12进行分析
3.进一步体会到利用F12进行抓包的重要性

附:浏览器F12调试分析的过程

posted @ 2021-10-13 20:25  penguin02  阅读(25)  评论(0编辑  收藏  举报