数据采集与融合实践第三次实践作业:在中国气象网爬取网站的所有图片、scrapy爬取东方财富网的数据并存储到数据库中、爬取中国银行网的外汇数据并存储到数据库中
作业1
在中国气象网爬取网站的所有图片
- Gitte文件夹链接:https://gitee.com/prettykuromi/102102137/tree/master/作业3/问题1
- 首先创建scrapy项目,完成settings.py、run.py等基础文件的编写
- 分析,要想爬取网站的所有图片,实际上只要获取页面中的a元素的href链接用于跳转,对于单个页面,获取所有img元素的src并下载图片即可。
- 分析页面,发现img元素的src内是完整的下载网址,因此无需补充完整,myspider.py文件中实现如下代码
# 找到img元素
images = selector.xpath("//img")
for image in images:
# 获取图片下载地址
img = image.xpath('@src').extract_first()
item = WeatherItem()
item["url"] = img.strip() if img else ""
yield item
- 实现翻页,为了控制总页数小于37,每次翻页前增加判断,注意翻页前让程序暂停一会,防止过分频繁的页面请求导致对网址服务器造成骚扰,myspider.py文件中实现如下代码
#部分代码
pages = selector.xpath("//a/@href").extract()
for idx, page in enumerate(pages):
self.count += 1
if self.count <= 37:
url = page
time.sleep(2)
yield scrapy.Request(url=url, callback=self.parse)
- 在pipelines.py文件中,接收传送的url并实现图片下载,首先实现单线程下载。需要限制下载的图片数小于137,同时动态获取图片扩展名
if self.index<=137:
img_url = item["url"]
extension = os.path.splitext(img_url)[1] # 获取扩展名
# 生成文件名
imagename = f"D:/images/{self.index}.{extension}"
self.index += 1
# 输出下载的url信息
print(img_url)
# 单线程下载图片
urllib.request.urlretrieve(img_url,filename=imagename)
self.count += 1
else:
self.opened = False
for index, img_url in enumerate(rows):
thread_name = "thread" + str(index) # 构建线程名称
exec("%s = threading.Thread(target=thread, args=(index, img_url))" % thread_name)
threads.append(eval(thread_name))
eval(thread_name).start()
- 最终编写完整代码后,运行run.py文件
输出的url信息如下
下载到本地的137张图片,部分如下:
心得体会
- 下载图片的时候一定要注意url是否完整,同时动态获取图片的文件扩展名
- 使用scrapy编写爬虫项目时要了解scrapy的流程
- 做实验的时候不能心急,要细心仔细防止代码出bug
作业2
scrapy爬取东方财富网的数据并存储到数据库中
- Gittee文件夹链接:https://gitee.com/prettykuromi/102102137/tree/master/作业3/问题2
- 由于该网站的数据是使用json动态传递的,因此采取抓包的方法获取数据更为简单
- 分析该json文件,通过简单正则表达式匹配与转换,即可获取字典类型的数据,并获取所需的数据
dammit = UnicodeDammit(response.body, ["utf-8", "gbk"])
data = dammit.unicode_markup
pat = r'\[(.*?)\]' # 正则表达式
data = re.search(pat, data).group()
dataList = eval(data) # 现在data是一个数组,其中存放字典
# 分别在字典中提取所需信息
for data in dataList:
StockId = str(data['f12'])
Name = data['f14']
NewPrice = str(data['f2'])
UpDown = str(data['f3'])
DownUp = str(data['f4'])
DealNum = str(data['f5'])
DealPrice = str(data['f6'])
Up = str(data['f7'])
- 实现翻页,分析获取的json文件的url链接,并限制翻页页数
if self.page <= 7:
self.page += 1
url = f'https://69.push2.eastmoney.com/api/qt/clist/get?cb=jQuery112404359196896638151_1697701391202&pn={self.page+1}&pz=20&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&wbp2u=|0|0|0|web&fid=f3&fs=m:1+t:2,m:1+t:23&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&_=1697701391203'
time.sleep(2)
yield scrapy.Request(url=url, callback=self.parse)
- 在pipelines.py文件中,向mysql数据库中插入获取到的数据
if self.opened:
self.index+1
self.cursor.execute(
"insert into Stocks (StockId,Name,NewPrice,UpDown,DownUp,DealNum,DealPrice,Up) values(%s,%s,%s,%s,%s,%s,%s,%s)",
(item["StockId"], item["Name"], item["NewPrice"], item["UpDown"], item["DownUp"],
item["DealNum"], item["DealPrice"], item["Up"]))
self.count += 1
- 最终运行run.py文件,共获得180条数据,展示mysql数据库中的数据如下:
心得体会
- 在f12调试抓包时要留意数据所在的json文件,同时分析不同页面间的url的关系,以更好爬取数据
- 使用正则表达式时要细心,正确获取所需数据
- 使用mysql时要注意传送的数据类型和数据库中的类型一致
作业3
爬取中国银行网的外汇数据并存储到数据库中
- Gittee文件夹链接:https://gitee.com/prettykuromi/102102137/tree/master/作业3/问题3
- 首先f12进行抓包,发现该网页并没有使用ajax进行数据传递,因此采用常规的xpath分析获取所需数据。
需要注意,有些数据是空值,因此需要做特殊处理
tds = li.xpath("./td")
if tds:
name = tds[0].xpath('./text()').extract()[0] if tds[0].xpath('./text()').extract() else ""
nowbuy = tds[1].xpath('./text()').extract()[0] if tds[1].xpath('./text()').extract() else ""
moneybuy = tds[2].xpath('./text()').extract()[0] if tds[2].xpath('./text()').extract() else ""
nowseal = tds[3].xpath('./text()').extract()[0] if tds[3].xpath('./text()').extract() else ""
moneyseal = tds[4].xpath('./text()').extract()[0] if tds[4].xpath('./text()').extract() else ""
mid = tds[5].xpath('./text()').extract()[0] if tds[5].xpath('./text()').extract() else ""
date = tds[6].xpath('./text()').extract()[0] if tds[6].xpath('./text()').extract() else ""
time_ = tds[7].xpath('./text()').extract()[0] if tds[7].xpath('./text()').extract() else ""
- 同样需要实现翻页功能,分析url间关系,使用如下代码实现翻页且限制爬取页面数
if self.page <= 7:
self.page += 1
url=f'https://www.boc.cn/sourcedb/whpj/index_{self.page}.html'
time.sleep(2)
yield scrapy.Request(url=url, callback=self.parse)
- pipelines.py文件中,实现接收传递的数据并进行下载带mysql数据库中
if self.opened:
self.cursor.execute(
"insert into bank (name,nowbuy,moneybuy,nowseal,moneyseal,mid,date,time_) values(%s,%s,%s,%s,%s,%s,%s,%s)",
(item["name"], item["nowbuy"], item["moneybuy"], item["nowseal"], item["moneyseal"],
item["mid"], item["date"], item["time_"]))
self.count += 1
- 最终运行run.py文件,下载共243条数据,展示部分如下:
心得体会
- 获取页面数据时要注意观察、判断页面元素是否为空
- 存放数据库时注意检查数据是否有多余无用符号,比如多余的引号或括号,如有需要删除
- 存储数据到数据库中时要注意数据类型一致
本文暂时没有评论,来添加一个吧(●'◡'●)