資料採集作業二
課程連結 | https://edu.cnblogs.com/campus/fzu/2024DataCollectionandFusiontechnology |
---|---|
作業連結 | https://edu.cnblogs.com/campus/fzu/2024DataCollectionandFusiontechnology/homework/13285 |
作業連結 | https://gitee.com/jsjdjjdjajsd/getinformation/tree/master/作業二 |
學號姓名 | 102202119吳佳輝 |
作業1
1.資料採集實驗
要求:在中國氣象網(http://www.weather.com.cn)給定城市集的 7日天氣預報,並儲存在資料庫。
點選檢視程式碼
from bs4 import BeautifulSoup
from bs4.dammit import UnicodeDammit
import urllib.request
import mysql.connector
class WeatherDB:
def __init__(self):
self.cursor = None
self.con = None
def openDB(self):
self.con = mysql.connector.connect(
host="localhost",
user="root",
password="123456",
database="weather_db"
)
self.cursor = self.con.cursor()
try:
self.cursor.execute(
"CREATE TABLE IF NOT EXISTS weathers (wCity VARCHAR(16), wDate VARCHAR(16), wWeather VARCHAR(64), wTemp VARCHAR(32), PRIMARY KEY (wCity, wDate))"
)
except Exception as err:
print(err)
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 (%s, %s, %s, %s)",
(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 = {"鄭州": "101180101", "銀川": "101170101", "福州": "101230101", "北京": "101010100"}
def forecastCity(self, city):
if city not in self.cityCode.keys():
print(city + " 找不到程式碼")
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")
x = 0
for li in lis:
try:
date = li.select('h1')[0].text
weather = li.select('p[class="wea"]')[0].text
if x == 0:
x += 1
temp = li.select('p[class="tem"] i')[0].text
else:
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)
self.db.closeDB()
ws = WeatherForecast()
ws.process(["鄭州", "銀川", "福州", "北京"])
print("completed")
執行結果在mysql資料庫檢視
心得體會
在編寫這段天氣預報程式的過程中,我對Python在網路爬蟲和資料庫互動方面的應用有了更深的理解。透過使用BeautifulSoup庫解析HTML文件,我掌握瞭如何提取網頁中的特定資訊,比如天氣、日期和溫度。這讓我意識到,雖然獲取資訊的過程可能會受到頁面結構變化的影響,但靈活運用選擇器和異常處理可以有效提高程式碼的魯棒性。
此外,使用mysql.connector與MySQL資料庫進行互動讓我體會到資料持久化的重要性。在這段程式碼中,我建立了一個資料庫來儲存天氣資訊,這樣不僅可以方便後續查詢,也為資料分析打下了基礎。透過封裝成WeatherDB類,我能夠更好地管理資料庫的連線和操作,體現了物件導向程式設計的優勢。
在異常處理方面,程式碼中透過try-except結構來捕獲可能出現的錯誤,這增強了程式的穩定性,避免了因意外情況導致的程式崩潰。此外,使用使用者代理字串來模擬瀏覽器請求,有效地避免了因爬蟲檢測而導致的訪問限制。
總的來說,這段程式碼不僅是對技術的實踐,也是對程式設計思維的培養。讓我在實際專案中學習到了如何將不同模組結合在一起,從而實現複雜的功能。透過這次實踐,我對爬蟲技術和資料庫操作的理解更加深入,也激發了我對資料分析和應用開發的興趣。
作業二
1.資料採集實驗
要求:用 requests 和 BeautifulSoup 庫方法定向爬取股票相關資訊,並儲存在資料庫中。
候選網站:東方財富網:https://www.eastmoney.com/ 新浪股票:http://finance.sina.com.cn/stock/
點選檢視程式碼
import requests
import mysql.connector
import json
db_config = {
'user': 'root',
'password': '123456',
'host': 'localhost',
'database': 'stock_db'
}
conn = mysql.connector.connect(**db_config)
c = conn.cursor()
c.execute('''
CREATE TABLE IF NOT EXISTS stock_data (
id INT AUTO_INCREMENT PRIMARY KEY,
stock_code VARCHAR(10),
stock_name VARCHAR(50),
current_price DECIMAL(10, 2),
change_percent DECIMAL(5, 2),
change_amount DECIMAL(10, 2)
)
''')
url = "http://push2.eastmoney.com/api/qt/clist/get"
params = {
"pn": "1",
"pz": "20",
"po": "1",
"np": "1",
"ut": "bd1d9ddb04089700cf9c27f6f7426281",
"fltt": "2",
"invt": "2",
"fid": "f3",
"fs": "m:0+t:6",
"fields": "f1,f2,f3,f4,f12,f14"
}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"
}
response = requests.get(url, params=params, headers=headers)
data = response.json()
if data and data['data']:
stock_list = data['data']['diff']
stock_data = []
for stock in stock_list:
stock_code = stock['f12']
stock_name = stock['f14']
current_price = stock['f2']
change_percent = stock['f3']
change_amount = stock['f4']
stock_data.append((stock_code, stock_name, current_price, change_percent, change_amount))
c.executemany('''
INSERT INTO stock_data (stock_code, stock_name, current_price, change_percent, change_amount)
VALUES (%s, %s, %s, %s, %s)
''', stock_data)
conn.commit()
print("股票資料已成功儲存到資料庫。")
c.close()
conn.close()
心得體會
在編寫這段股票資料爬取並儲存到資料庫的程式碼過程中,我對Python的網路請求和資料庫操作有了更深的理解。首先,透過使用requests庫發起HTTP請求,我成功地從東方財富網獲取了實時的股票資料。這個過程讓我認識到,網路資料爬取的核心在於正確構造請求引數以及處理返回的JSON格式資料。
資料的解析和儲存是我學習的另一個重點。利用json庫將響應資料轉換為Python物件後,我透過遍歷獲取的股票列表,提取了所需的資訊。這一過程中,掌握瞭如何從複雜的資料結構中篩選出關鍵資訊。
在資料庫操作方面,我使用mysql.connector庫連線MySQL資料庫,並建立了一個儲存股票資料的表。透過封裝插入操作的SQL語句,使用executemany方法批次插入資料,這不僅提高了插入效率,也確保了資料的一致性。
此外,我認識到異常處理的重要性,儘管在這段程式碼中沒有加入異常處理,但在實際開發中,考慮網路請求失敗、資料庫連線問題等情況是非常必要的。整體來看,這段程式碼不僅讓我掌握了資料獲取與儲存的基本流程,還激發了我對資料分析和應用開發的濃厚興趣。透過實踐,我更加堅定了在資料科學領域深入探索的決心。
作業三
1.資料採集實驗
要求:爬取中國大學 2021 主榜(https://www.shanghairanking.cn/rankings/bcur/2021)所有院校資訊,並儲存在資料庫中,同時將瀏覽器 F12 除錯分析的過程錄製 Gif 加入至部落格中。
點選檢視程式碼
import requests
import re
import mysql.connector
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
class DB:
def open(self):
try:
self.connection = mysql.connector.connect(
host='localhost',
user='root',
password='123456',
database='school_db'
)
self.cursor = self.connection.cursor()
self.cursor.execute(
'CREATE TABLE IF NOT EXISTS schoolrank ('
'排行 INT AUTO_INCREMENT PRIMARY KEY, '
'學校 VARCHAR(16), '
'省市 VARCHAR(16), '
'型別 VARCHAR(16), '
'總分 FLOAT)'
)
except mysql.connector.Error as e:
logging.error(f"Error connecting to database: {e}")
def close(self):
try:
self.connection.commit()
self.cursor.close()
self.connection.close()
except Exception as e:
logging.error(f"Error closing database connection: {e}")
def insert(self, name, province, cata, score):
try:
score = float(score)
self.cursor.execute(
'INSERT INTO schoolrank (學校, 省市, 型別, 總分) VALUES (%s, %s, %s, %s)',
(name, province, cata, score)
)
logging.info(f"Inserted: {name}, {province}, {cata}, {score}")
except ValueError as ve:
logging.warning(f"ValueError: {ve} - Invalid score value for {name}. Skipping this entry.")
except Exception as e:
logging.error(f"Error inserting data: {e}")
url = r'https://www.shanghairanking.cn/_nuxt/static/1728872418/rankings/bcur/2021/payload.js'
req = requests.get(url)
req.raise_for_status()
req.encoding = req.apparent_encoding
data = req.text
univerCnlist = re.findall('univNameCn:"(.*?)",', data)
provincelist = re.findall('province:(.*?),', data)
univerCategorylist = re.findall('univCategory:(.*?),', data)
scorelist = re.findall('score:(.*?),', data)
logging.info(f"University Count: {len(univerCnlist)}")
func_data_key = data[len('__NUXT_JSONP__("/rankings/bcur/2021", (function('):data.find(')')].split(',')
func_data_value = data[data.rfind('(') + 1:-4].split(',')
mydict = {key: value for key, value in zip(func_data_key, func_data_value)}
name = univerCnlist
province = [mydict[item] for item in provincelist]
cate = [mydict[item] for item in univerCategorylist]
db = DB()
db.open()
for i in range(len(name)):
db.insert(name[i], province[i], cate[i], scorelist[i])
db.close()
心得體會
在實現這段程式碼的過程中,我對資料抓取和資料庫操作的整體流程有了更深入的理解。首先,透過requests庫向目標URL發起請求,成功獲取了包含大學排名資訊的JavaScript資料。這一部分讓我認識到,HTTP請求和響應的處理是網路資料獲取的基礎。
接著,我使用正規表示式從返回的文字中提取了有用的資料,如大學名稱、省市、型別和分數。這一過程讓我體會到,資料清洗和提取在實際應用中是多麼重要,尤其是在處理不規則的資料格式時。
在資料庫操作方面,我建立了一個資料庫連線並構建了表結構,使用mysql.connector庫進行資料插入。這讓我認識到,資料庫的設計和操作需要與資料的結構緊密結合。在插入資料時,注意到資料型別的轉換,如將分數轉為浮點數,以確保資料的準確性。
此外,設定日誌記錄功能使我能夠實時監控程式的執行狀態,及時捕捉並處理可能出現的異常。這一點對於維護程式碼的穩定性和可除錯性至關重要。
總的來說,這段程式碼的實現不僅提升了我的程式設計技能,還增強了我對資料處理和儲存流程的理解,使我更加期待在資料分析和工程領域的進一步探索。