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

发布时间 2023-10-14 15:16:23作者: 李波102102157

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

作业①:

  1. 要求:在中国气象网(http://www.weather.com.cn)给定城市集的7日天气预报,并保存在数据库。
  2. 输出信息:
  3. Gitee文件夹链接

1代码内容运行结果和Gitee链接

import sqlite3
from bs4 import BeautifulSoup
from bs4 import UnicodeDammit
import urllib.request

url="http://www.weather.com.cn/weather/101040100.shtml"

forecast_data = []
try:
    headers={"User-Agent":"Mozilla/5.0 (Windows; U; Windows NT 6.0 x64; en-US; rv:1.9pre) Gecko/2008072421 Minefield/3.0.2pre"}
    req=urllib.request.Request(url,headers=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
            forecast_data.append((date, weather, temp))
            print(date,weather,temp)
        except Exception as err:
            print(err)
except Exception as err:
    print(err)

# 连接到数据库并保存数据
conn = sqlite3.connect('weather.db')  # 创建数据库连接
cursor = conn.cursor()

# 创建天气预报表(如果不存在)
cursor.execute('''CREATE TABLE IF NOT EXISTS forecast
                  (date TEXT, weather TEXT, temperature TEXT)''')

# 插入数据到天气预报表
cursor.executemany('INSERT INTO forecast VALUES (?, ?, ?)', forecast_data)

# 提交事务并关闭连接
conn.commit()
conn.close()

print("天气预报已成功保存到数据库。")

运行结果:

Gitee链接:
https://gitee.com/li-bo-102102157/libo_project/commit/60b0ac66c2867381eb2524a2e799398350967fce

2.心得体会

第一个作业比较好完成,进行复现即可。我只是完成了数据库的创建和连接,相对来说还是容易完成的。

作业②

  1. 要求:用requests和BeautifulSoup库方法定向爬取股票相关信息,并存储在数据库中。
  2. 候选网站:东方财富网:https://www.eastmoney.com/
  3. 新浪股票:http://finance.sina.com.cn/stock/
  4. 技巧:在谷歌浏览器中进入F12调试模式进行抓包,查找股票列表加载使用的url,并分析api返回的值,并根据所要求的参数可适当更改api的请求参数。根据URL可观察请求的参数f1、f2可获取不同的数值,根据情况可删减请求的参数。
  5. 参考链接:https://zhuanlan.zhihu.com/p/50099084
  6. 输出信息:
  7. Gitee文件夹链接

1代码内容运行结果和Gitee链接

import json
import requests
import sqlite3


def get_html():
    url = "http://38.push2.eastmoney.com/api/qt/clist/get?cb=jQuery112407987064832629414_1696658970374&pn=1&pz=20&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&wbp2u=%7C0%7C0%7C0%7Cweb&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&_=1696658970375"
    response = requests.get(url)

    try:
        # 从响应内容中提取有效的 JSON 部分
        jsonp = response.text
        json_data = jsonp[jsonp.index('(') + 1: jsonp.rindex(')')]

        # 解析为 Python 对象
        data = json.loads(json_data)
        return data

    except (json.JSONDecodeError, ValueError) as e:
        print("JSON解析错误:", str(e))
        print("实际响应内容:", response.text)
        return None


def create_table(cursor):
    # 创建表格(如果不存在)
    create_table_query = '''
    CREATE TABLE IF NOT EXISTS stock_data (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        code VARCHAR(10),
        name VARCHAR(255),
        price DECIMAL(10, 2),
        change_percent DECIMAL(10, 2),
        change_amount DECIMAL(10, 2),
        volume BIGINT,
        turnover DECIMAL(18, 2),
        increase_percent DECIMAL(10, 2)
    )
    '''
    cursor.execute(create_table_query)


def insert_data(cursor, item):
    code = item["f12"]
    name = item["f14"]
    price = float(item["f2"])
    change_percent = float(item["f3"])
    change_amount = float(item["f4"])
    volume = int(item["f5"])
    turnover = float(item["f6"])
    increase_percent = float(item["f7"])

    insert_query = '''
    INSERT INTO stock_data (code, name, price, change_percent, change_amount, volume, turnover, increase_percent)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?)
    '''
    cursor.execute(insert_query, (code, name, price, change_percent, change_amount, volume, turnover, increase_percent))


def save_to_database(data):
    conn = sqlite3.connect('股票.db')
    with conn:
        cursor = conn.cursor()

        create_table(cursor)

        # 插入数据
        for item in data["data"]["diff"]:
            insert_data(cursor, item)

    print("数据已保存到数据库文件。")


def fetch_data_from_database():
    conn = sqlite3.connect('股票.db')
    with conn:
        cursor = conn.cursor()

        # 查询数据
        select_query = "SELECT * FROM stock_data"
        cursor.execute(select_query)

        # 获取结果并打印
        results = cursor.fetchall()
        for row in results:
            id, code, name, price, change_percent, change_amount, volume, turnover, increase_percent = row
            print(
                f"{id}\t{code}\t{name}\t{price}\t{change_percent}\t{change_amount}\t{volume}\t{turnover}\t{increase_percent}")


if __name__ == '__main__':
    data = get_html()
    if data:
        save_to_database(data)
        fetch_data_from_database()

运行结果:

Gitee链接:
https://gitee.com/li-bo-102102157/libo_project/commit/c694496aa0d9047b738df015480e333ebd6182ca

2.心得体会

这段代码实现了股票数据的抓取和存储功能,使用了第三方库requests和内置库sqlite3。从抓取数据的流程可以看出,首先发送网络请求获取响应,然后从响应中提取有效的JSON数据,并解析为Python对象。接下来,创建SQLite数据库表格,定义插入数据和查询数据的函数,并使用这些函数将抓取到的股票数据存储到数据库中。最后,从数据库中读取数据并打印出来。

作业③:

  1. 要求:爬取中国大学2021主榜(https://www.shanghairanking.cn/rankings/bcur/2021)所有院校信息,并存储在数据库中,同时将浏览器F12调试分析的过程录制Gif加入至博客中。
  2. 技巧:分析该网站的发包情况,分析获取数据的api
  3. 输出信息:
  4. Gitee文件夹链接

1代码内容运行结果和Gitee链接

import requests
import sqlite3

province_dict = {
    "y": "安徽",
    "q": "北京",
    "C": "上海",
    "D": "福建",
    "u": "广东",
    "o": "河南",
    "k": "江苏",
    "r": "辽宁",
    "Q": "青海",
    "t": "四川",
    "M": "天津",
    "aF": "西藏",
    "F": "云南",
    "x": "浙江",
    "v": "湖北",
    "s": "陕西",
    "A": "黑龙江",
    "n": "山东",
    "w": "湖南",
    "B": "吉林",
    "J": "甘肃",
    "G": "广西",
    "K": "内蒙古",
    "N": "新疆",
    "I": "贵州",
    "Y": "海南",
    "aD": "宁夏",
    "aE": "青海",
    "z": "江西",
    "L": "重庆",
    "E": "山西",
    "p": "河北"

}

url = r'https://www.shanghairanking.cn/_nuxt/static/1697106492/rankings/bcur/2021/payload.js'
forecast_data = []
r = requests.get(url, timeout=20)
if r.status_code == 200:
    r.encoding = 'utf-8'
    content = r.text
    colleges = []

    while content.find('univNameCn:"') != -1:
        acollege = []
        # 大学名称
        content = content[content.find('univNameCn:"') + 12:]
        collegeName = content[:content.find('"')]
        acollege.append(collegeName)

        # 省份
        content = content[content.find('province:') + 9:]
        province_code = content[:content.find(',')]
        province = province_dict.get(province_code, "未知")  # 使用字典进行映射,如果没有找到对应省份,默认为"未知"
        acollege.append(province)

        # 总分
        content = content[content.find('score:') + 6:]
        score = content[:content.find(',')]
        acollege.append(score)

        colleges.append(acollege)

    print(len(colleges))
    # print(colleges)
    print("{:^10}\t{:^6}\t{:^6}\t{:^6}".format("排名", "学校名称", '省份', '分数'))
    num = 10
    for i in range(len(colleges)):
        print("{:^10}\t{:^6}\t{:^6}\t{:^6}".format(str(i + 1), colleges[i][0], colleges[i][1], colleges[i][2]))

    # 将数据保存到数据库
    conn = sqlite3.connect('university_ranking.db')  # 连接数据库,如果不存在则创建
    c = conn.cursor()

    # 创建表格
    c.execute('''CREATE TABLE IF NOT EXISTS universities 
                 (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, province TEXT, score REAL)''')

    # 插入数据
    for college in colleges:
        c.execute("INSERT INTO universities (name, province, score) VALUES (?, ?, ?)", college)

    conn.commit()  # 提交事务
    conn.close()  # 关闭数据库连接

    print("数据已保存到数据库中。")

页面查看结果

运行结果:

Gitee链接:
https://gitee.com/li-bo-102102157/libo_project/commit/984602ea36ae84f7f1763999d8852a93ae5ddc4e

2.心得体会

这段代码实现了从指定网址抓取大学排名数据,并将数据存储到SQLite数据库中。首先通过requests库发送网络请求获取网页内容,然后使用字符串操作和字典映射等方式提取出需要的数据。接着,创建了一个数据库连接,并通过执行SQL语句创建了名为universities的表格。然后,使用循环将抓取到的大学信息逐条插入到表格中。最后,提交事务并关闭数据库连接。