数据采集第二次大作业
第二次大作业
作业1
1.1实验题目
- 要求:在中国气象网(http://www.weather.com.cn)给定城市集的7日天气预报,并保存在数据库。
- 输出信息:
序号 | 地区 | 日期 | 天气信息 | 温度 |
1 | 北京 | 7日(今天) | 晴间多云,北部山区有阵雨或雷阵雨转晴转多云 | 31℃/17℃ |
2 | 北京 | 8日(明天) | 多云转晴,北部地区有分散阵雨或雷阵雨转晴 | 34℃/20℃ |
3 | 北京 | 9日(后台) | 晴转多云 | 36℃/22℃ |
4 | 北京 | 10日(周六) | 阴转阵雨 | 30℃/19℃ |
5 | 北京 | 11日(周日) | 阵雨 | 27℃/18℃ |
6...... |
1.2思路
1.2.1天气预报数据爬取
在打开中国气象网(http://www.weather.com.cn)搜索指定的城市后,下图中对应的黄色部分是不一样的,所以以此来标记不同的地区。
分别查询想要爬取城市的对应部分,形成字典,分别调取对应部分对数据进行爬取。
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 = {"福州": "101230101", "上海": "101020100", "广州": "101280101", "深圳": "101280601"}
1.2.2数据库存储数据
核心代码
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]))
1.2.3数据库的创建,打开和关闭
def process(self, cities):
self.db = WeatherDB()
self.db.openDB()
for city in cities:
self.forecastCity(city)
self.db.closeDB()
1.2.4结果
控制台输出结果
数据库中结果
1.3完整代码
https://gitee.com/q_kj/crawl_project/blob/master/second/1.py
1.4总结
这题主要是运行老师所给的范例,但是通过这题也了解了sqlite数据库
存储数据的方法。
作业2
2.1实验题目
-
要求:用requests和BeautifulSoup库方法定向爬取股票相关信息。
-
候选网站:东方财富网:http://quote.eastmoney.com/center/gridlist.html#hs_a_board
-
技巧:在谷歌浏览器中进入F12调试模式进行抓包,查找股票列表加载使用的url,并分析api返回的值,并根据所要求的参数可适当更改api的请求参数。根据URL可观察请求的参数f1、f2可获取不同的数值,根据情况可删减请求的参数。
-
输出信息:
序号 | 股票代码 | 股票名称 | 最新报价 | 涨跌幅 | 涨跌额 | 成交量 | 成交额 | 振幅 | 最高 | 最低 | 今开 | 昨收 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 688093 | N世华 | 28.47 | 62.22% | 10.92 | 26.13万 | 7.6亿 | 22.34 | 32.0 | 28.08 | 30.2 | 17.55 |
2...... |
2.2思路
2.2.1股票爬取
在通过F12
抓包后,得到股票的包,可以对照发现所需要的数据,如下图
例如股票代码为f12
,对照数据,可以得到想要数据对应的标签,再通过re
正则表达式的方式对数据进行提取。
stock_no = re.findall('"f12":"(.*?)"', data)
stock_name = re.findall('"f14":"(.*?)"', data)
new_price = re.findall('"f2":(.*?),', data)
hl_rate = re.findall('"f3":(.*?),', data)
ud = re.findall('"f4":(.*?),', data)
turnover = re.findall('"f5":(.*?),', data)
number_change = re.findall('"f6":(.*?),', data)
ampl = re.findall('"f7":(.*?),', data)
highest = re.findall('"f15":(.*?),', data)
mininum = re.findall('"f16":(.*?),', data)
open_t = re.findall('"f17":(.*?),', data)
close_y = re.findall('"f18":(.*?),', data)
2.2.2数据库存储
和第一题基本上一致,只是存储的列数和对应的标题不一样
class StockDB:
def openDB(self):
self.con=sqlite3.connect("stocks.db")
self.cursor=self.con.cursor()
try:
self.cursor.execute('''create table stocks (序号 varchar(16), 股票代码 varchar(16), 股票名称 varchar(16),
最新报价 varchar(16),涨跌幅 varchar(16),涨跌额 varchar(16),成交量 varchar(16),
成交额 varchar(16),振幅 varchar(16),最高 varchar(16),最低 varchar(16),
今开 varchar(16),昨收 varchar(16),constraint pk_weather primary key (股票代码))''')
except:
self.cursor.execute("delete from stocks")
def closeDB(self):
self.con.commit()
self.con.close()
def insert(self, stock_rank, stock_no, stock_name, new_price, hl_rate, ud, turnover, number_change, ampl, highest, mininum, open_t, close_y):
try:
self.cursor.execute('''insert into stocks(序号, 股票代码, 股票名称,
最新报价, 涨跌幅 ,涨跌额 ,成交量 ,成交额 ,振幅 ,最高 ,最低 ,今开 ,昨收) values (?,?,?,?,?,?,?,?,?,?,?,?,?)''',
(stock_rank, stock_no, stock_name, new_price, hl_rate, ud, turnover, number_change, ampl, highest, mininum, open_t, close_y))
except Exception as err:
print(err)
def show(self):
self.cursor.execute("select * from weathers")
rows = self.cursor.fetchall()
print("%-16s%-16s%-16s%-16s%-16s%-16s%-16s%-16s%-16s%-16s%-16s%-16s%-16s" % ("序号", "股票代码", "股票名称", "最新报价","涨跌幅","涨跌额","成交量","成交额","振幅","最高","最低","今开","昨收"))
for row in rows:
print("%-16s%-16s%-16s%-16s%-16s%-16s%-16s%-16s%-16s%-16s%-16s%-16s%-16s" % (row[0], row[1], row[2], row[3],row[4], row[5], row[6], row[7],row[8], row[9], row[10], row[11],row[12]))
2.2.3结果
控制台结果
数据库结果
2.3完整代码
https://gitee.com/q_kj/crawl_project/blob/master/second/2.py
2.4总结
(1)首先这是第一次通过F12来抓取包来仔细分析,之前在爬取淘宝商品信息的时候虽然也通过这种方法来获得cookie,但是没有仔细分析包,感觉F12
加上re
正则表达式的使用可以更加简单的获取数据;
(2)通过改写第一题老师所给范例中创建数据库,表,插入数据等方法,更加了解sqlite
数据库的使用。
(3)但是“上证指数”和其他是放在同一个表中,我在思考如何讲其存入不同的表中,但是最近一直很忙没有动手,记在这里省的忘了。
作业3
3.1实验题目
- 要求: 爬取中国大学2021主榜 https://www.shanghairanking.cn/rankings/bcur/2021
所有院校信息,并存储在数据库中,同时将浏览器F12调试分析的过程录制Gif加入至博客中。 - 技巧: 分析该网站的发包情况,分析获取数据的api
- 输出信息:
排名 | 学校 | 总分 |
---|---|---|
1 | 清华大学 | 969.2 |
3.2思路
3.2.1F12
调试分析过程
通过爬取的js包,分析得到学校名称在univNameCn
和总分在score
标签中,如下图:
3.2.2学校信息爬取
由上面所讲,通过re
正则表达式来匹配得到所要的信息。
name = re.findall(r'univNameCn:"(.*?)"', data)
score = re.findall(r'score:(.*?),', data) # 匹配所有的大学分数
3.2.3数据库存储
class SchoolDB:
def openDB(self):
self.con=sqlite3.connect("schools.db")
self.cursor=self.con.cursor()
try:
self.cursor.execute("create table schools (排名 varchar(16),学校 varchar(16),总分 varchar(16),constraint pk_weather primary key (学校))")
except:
self.cursor.execute("delete from schools")
def closeDB(self):
self.con.commit()
self.con.close()
def insert(self, rank, name, score):
try:
self.cursor.execute("insert into schools (排名, 学校 ,总分) values (?,?,?)",(rank, name, score))
except Exception as err:
print(err)
def show(self):
#self.cursor.execute("select * from weathers")
rows = self.cursor.fetchall()
print("%-16s%-16s%-16s" % ("排名", "学校", "总分"))
for row in rows:
print("%-16s%-16s%-16s" % (row[0], row[1], row[2]))
3.2.4结果
控制台结果
数据库结果
3.3完整代码
https://gitee.com/q_kj/crawl_project/blob/master/second/3.py
3.4总结
仍然是改写老师所给代码来用数据库存储数据;三道题的方法十分类似,只要写了一题,剩下都只要改一下url,数据匹配的正则表达式以及表就好了。