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

发布时间 2023-10-18 18:55:45作者: liannnn

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

·Gitee文件夹链接:https://gitee.com/lian111111/crawl_project/tree/master/数据采集与融合技术第二次作业/作业2.1
实验内容
代码如下:

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 IF NOT EXISTS weathers (wCity VARCHAR(16), wDate VARCHAR(16), wWeather VARCHAR(64), wTemp VARCHAR(32), PRIMARY KEY (wCity, wDate))")
		except Exception:
			pass

	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 sqlite3.IntegrityError:
			pass
		except Exception:
			pass


class WeatherForecast:
	def __init__(self, db):
		self.db = db
		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", "福州": "101230101"}

	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")

			print(f"天气信息 for {city}:")
			print("序号\t地区\t日期\t天气信息\t温度")
			for i, li in enumerate(lis, start=1):
				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(f"{i}\t{city}\t{date}\t{weather}\t{temp}")
					self.db.insert(city, date, weather, temp)
				except Exception:
					pass
		except Exception:
			pass


db = WeatherDB()
db.openDB()

ws = WeatherForecast(db)
ws.forecastCity("北京")
ws.forecastCity("上海")
ws.forecastCity("广州")
ws.forecastCity("深圳")
ws.forecastCity("福州")

db.closeDB()
print("completed")

运行结果如下:
image

心得体会
通过对课例的实践,对bs库有了更深的认识,学会了使用sqlite3查看保存的数据。

作业②
实验要求
·要求:用 requests 和 BeautifulSoup 库方法定向爬取股票相关信息,并存储在数据库中。

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

·Gitee文件夹链接:https://gitee.com/lian111111/crawl_project/tree/master/数据采集与融合技术第二次作业/作业2.2

实验内容
代码如下:

import requests
from bs4 import BeautifulSoup
import pandas as pd
import time

def fetch_stock_data():
	print("开始运行脚本...")

	# 存储所有页的股票数据
	all_data = pd.DataFrame()

	# 爬取前 n 页的数据
	num_pages_to_scrape = 5
	url = 'http://quote.eastmoney.com/center/gridlist.html#sz_a_board'

	for page in range(1, num_pages_to_scrape + 1):
		try:
			print(f"获取第 {page} 页数据...")

			# 模拟构造 AJAX 请求的 URL,通常需要分析网站的网络请求
			ajax_url = f'{url}?page={page}'  

			response = requests.get(ajax_url)
			response.raise_for_status()  # 检查请求是否成功

			soup = BeautifulSoup(response.text, 'html.parser')

			# 查找和解析表格数据
			table = soup.find('table')
			df = pd.read_html(str(table), header=0)[0]

			# 删除 "相关链接" 和 "加自选" 列,如果有的话
			if '相关链接' in df.columns:
				df = df.drop(columns=['相关链接'])
			if '加自选' in df.columns:
				df = df.drop(columns=['加自选'])

			# 确保股票代码是6位数,填充前导0
			df['代码'] = df['代码'].apply(lambda x: str(x).zfill(6))

			# 添加数据到总的 DataFrame 中
			all_data = pd.concat([all_data, df], ignore_index=True)

			# 暂停,防止对服务器的过度请求
			time.sleep(5)

		except Exception as e:
			print("获取数据时出错:", e)
			break  # 如果出错,停止爬取

	print(all_data)

	# 保存数据到 CSV 文件
	all_data.to_csv('stocks.csv', index=False, encoding='utf-8-sig')

	print("数据保存成功。")

# 运行函数
fetch_stock_data()

运行结果:
image
数据库中:
image

心得体会:
通过本题的实践,对抓包的方式有了一定的了解与学习。

作业③:
实验要求
·要求:爬取中国大学 2021 主榜(https://www.shanghairanking.cn/rankings/bcur/2021)所有院校信息,并存储在数据库中,同时将浏览器 F12 调试分析的过程录制 Gif 加入至博客中。
·技巧:分析该网站的发包情况,分析获取数据的 api

·Gitee文件夹链接:https://gitee.com/lian111111/crawl_project/tree/master/数据采集与融合技术第二次作业/作业2.3
调试过程:
https://img2020.cnblogs.com/blog/2536706/202110/2536706-20211026195134069-1071385524.gif

实验内容
代码展示:

from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
import pandas as pd
import time

# 准备数据列表
data_list = []

# 定义获取表格数据的函数
def get_table_data(driver):
	try:
		rows = driver.find_elements_by_xpath('//tbody/tr')
		for row in rows:
			columns = row.find_elements_by_tag_name('td')
			ranking = int(columns[0].text)
			university = columns[1].text
			province = columns[2].text
			type_ = columns[3].text
			score = float(columns[4].text)
			data_list.append([ranking, university, province, type_, score])
	except Exception as e:
		print(f"Error occurred: {e}")

def get_data_from_website(url):
	# 启动 Chrome 浏览器
	driver = webdriver.Chrome()

	try:
		# 请求网页
		driver.get(url)

		# 获取第一页的数据
		get_table_data(driver)

		# 点击下一页并获取数据
		for _ in range(19):
			next_page_button = driver.find_element_by_css_selector('[title="下一页"]')
			next_page_button.click()
			time.sleep(5)  # 增加等待时间以确保页面完全加载
			get_table_data(driver)
	except NoSuchElementException:
		print("Cannot find the next page button. Maybe we reached the last page.")
	except Exception as e:
		print(f"An unexpected error occurred: {e}")
	finally:
		# 关闭浏览器
		driver.quit()

def save_data_to_excel(data, filename):
	# 将数据存储到 DataFrame
	df = pd.DataFrame(data, columns=['排名', '学校', '省市', '类型', '总分'])

	# 将 DataFrame 保存为 Excel 文件
	with pd.ExcelWriter(filename, engine='xlsxwriter') as writer:
		df.to_excel(writer, index=False, sheet_name='Sheet1')

	print(f"数据已保存到 '{filename}' 文件。")

# 主程序
if __name__ == "__main__":
	url = "https://www.shanghairanking.cn/rankings/bcur/2021"
	get_data_from_website(url)
	save_data

运行结果:
image

查看数据库中情况
image

心得体会
熟悉调试分析网页并利用js文件爬取信息