导航

数据采集与融合技术实践作业二

Posted on 2023-10-09 15:06    阅读(42)  评论(0编辑  收藏  举报

数据采集与融合技术实践作业二

                                                                                   102102136 陈耕

作业1:

(1)作业内容

实验要求:

在中国气象网(http://www.weather.com.cn)给定城市集的7日天气预报,并保存在数据库。

输出信息:

image

码云链接:

https://gitee.com/chen-pai/box/blob/master/实践课第二次作业/存天气1.py

代码内容:

# 导入
import urllib.request
import sqlite3
from bs4 import BeautifulSoup
from bs4 import UnicodeDammit

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)

        print("\n")
        print("开始输出数据库:\n")

        self.db.show()
        self.db.closeDB()

WF = WeatherForecast()
WF.process(["北京", "上海", "广州", "深圳"])
print("\n")
print("输出数据库完成")

具体实现:

image

产生了一个weathers.db,上述代码实现了weathers.db的导出查看。
image

(2)心得体会:

本次实验是对之前实验的复现,相较之下对数据库的生成、存储、查看、插入数据等操作有了更多的了解,更加巩固了对BeautifulSoup的使用和爬取网页的大致流程。

作业2:

(1)作业内容

实验要求:

用 requests 和 BeautifulSoup 库方法定向爬取股票相关信息,并存储在数据库中。

候选网站

东方财富网:https://www.eastmoney.com/
新浪股票:http://finance.sina.com.cn/stock/

技巧

在谷歌浏览器中进入 F12 调试模式进行抓包,查找股票列表加载使用的 url,并分析 api 返回的值,并根据所要求的参数可适当更改api 的请求参数。根据 URL 可观察请求的参数 f1、f2 可获取不同的数值,根据情况可删减请求的参数。

参考链接

https://zhuanlan.zhihu.com/p/50099084

输出信息:

image

码云链接:

https://gitee.com/chen-pai/box/blob/master/实践课第二次作业/爬股票.py

代码内容:

# 导入
import json
import re
import requests
import pandas as pd

def gethtml(page):
    url = "http://44.push2.eastmoney.com/api/qt/clist/get?cb=jQuery112406854618710877052_1696660618066&pn=" + str(page) + "&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=f2,f3,f4,f5,f6,f7,f12,f14&_=1696660618067"
    resquest = requests.get(url)
    # print(resquest.text)
    start = resquest.text.find('(')
    end = resquest.text.rfind(')')
    data = resquest.text[start+1:end]
    # print(data)
    data = json.loads(data)
    data = data['data']['diff']
    return data

def getdata(page):
    data = gethtml(page)
    name = ['f12','f14','f2','f3','f4','f5','f6','f7']
    global count
    list_data = []
    for i in range(len(data)):
        list = []
        list.append(i)
        for j in name:
            list.append(data[i][j])
        count += 1
        list_data.append(list)
    return list_data
# print(gethtml(1))
# print(getdata(1))
count = 1
data = []
n = int(input("请输入想要爬取的页面:"))
for i in range(1,n+1):
    k = getdata(i)
    # print(k)
    for i in k:
        data.append(i)
    # print(data,len(data))
df = pd.DataFrame(data=data,columns=['序号','代码','名称','最新价','涨跌幅','跌涨额','成交量','成交额','涨幅'])
print(df)

具体实现:

image

(2)心得体会:

1.了解到了网页数据是动态加载的,首先需要通过js文件获取数据所在的url,明白了动态加载的网页数据的爬取过程和如何通过查看js文件获取数据所在的url;
2.熟悉了翻页处理来获取不同模块以及页数上的股票信息,所以通过修改url的对应的值来达到翻页以及查看不同模块的效果;
3.学会了使用pd.DataFrame的相关语句来完成数据库的相关操作。

作业3:

(1)作业内容

实验要求:

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

技巧

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

输出信息:

image

F12的抓包过程

image

码云链接:

https://gitee.com/chen-pai/box/blob/master/实践课第二次作业/爬大学1.py

代码内容:

import requests
import pandas as pd
import re

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

resquest = requests.get(url=url)

name = re.findall(',univNameCn:"(.*?)",',resquest.text)#获取学校名称
score = re.findall(',score:(.*?),',resquest.text)#获取学校总分
category = re.findall(',univCategory:(.*?),',resquest.text)#获取学校类型
province = re.findall(',province:(.*?),',resquest.text)#获取学校所在省份

code_name = re.findall('function(.*?){',resquest.text)
start_code = code_name[0].find('a')
end_code = code_name[0].find('pE')
code_name = code_name[0][start_code:end_code].split(',')#将function中的参数取出并存在code_name列表中

value_name = re.findall('mutations:(.*?);',resquest.text)
start_value = value_name[0].find('(')
end_value = value_name[0].find(')')
value_name = value_name[0][start_value+1:end_value].split(",") #将参数所对应的含义取出存在value_name列表中

df = pd.DataFrame(columns=["排名","学校","省份","类型","总分"])
for i in range(len(name)):
    province_name = value_name[code_name.index(province[i])][1:-1]
    category_name = value_name[code_name.index(category[i])][1:-1]
    df.loc[i] = [i+1,name[i],province_name,category_name,score[i]]
print(df)
df.to_excel("test3_school.xlsx")

具体实现:

image

导出的 test3_school.xlsx 在excel表中打开:
image

(2)心得体会:

与上一题的处理方法类似,体会到了通过抓包来进行爬取。