1. 编者按
终于。。。利用零散时间,跟着B站学习了几天的视频后,终于具备了初步的爬虫本领。由于我个人是零基础学Python,零基础学爬虫。在半个月零散时间的尝试后,给自己布置了一个作业,爬取中国长征系列火箭发射记录。
利用的知识点包括:
1. 使用的库:requests,bs4,os,csv等;
2. 爬取指定网站的表格;
3. 处理翻页时URL不更新问题。
2. 需求分析
CZ系列运载火箭作为我国的金名片,以优质、高效、低成本等优势闻名海外,那么你知道我国CZ系列火箭都在哪些发射场发射过,哪个月份是火箭发射的高峰期,哪个发射场承担过最多的火箭发射任务。为了获取以上数据,我们今天就爬取数据分析一下。
爬取数据的具体实现步骤:
1. 获取URL:获取包含以上数据的URL地址;
2. 访问URL并得到响应,获取响应内容;
3. 对网页进行检查,并定位至感兴趣的信息处;
4. 提取文字内容;
5. 将文字内容存储在csv文件中查看。
废话不多说,下面正式开始。
3. URL地址的获取
长征火箭当然是中国航天科技集团下的拳头产品,想要获取响应信息,当然要登录科技集团或者航天一院的官方网站进行查找,经过一番摸索可以在中国运载火箭技术研究院的官网上获取地址:
http://www.calt.com/n482/n505/index.html
4. 准备工作
首先导入需要使用的Python库:
import requests
import os
import csv
from bs4 import BeautifulSoup
使用os库中的函数在电脑硬盘内创建数据存储对象
if not os.path.exists('D:/Data-SD/火箭发射数据'):
os.mkdir('D:/Data-SD/火箭发射数据')
5. 访问URL并得到响应
得到URL地址,同时进行UA伪装。
# 指定URL
url = 'http://www.calt.com/n482/n505/index.html'
# UA 伪装:将对应的user agent封装到一个字典中
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36'
}
使用requests库访问URL地址,并得到响应。由于这里使用BS4进行爬虫,因此得到网站的HTML格式文件。
这里注意一下:
因为处理的网页中有中文,因此要对获取响应的编码方式进行处理,如果处理的都似乎英文字符,则可以直接使用requests.get(url,headers).text获取内容,如果有中文要单独对获取的响应进行处理
responce.encoding = 'utf-8'
response = requests.get(url,headers=headers)#访问url
response.encoding = 'utf-8'
page_text = response.text
6. 对网页进行检查,信息定位
本章是重要的一个内容,主要对网站内容进行检查,用chrome浏览器,按下F12进行网页检查:
费了一番牛劲,终于找到了表格对应的标签!找到后先找class,发现没有。但是有一个ID = ‘comp_3805’,用这个可以定位吗。
试了下,发现可以啊!按照这个ID对表格内容进行寻找,并得到全部的tr(find_all('tr'))
soup = BeautifulSoup(response.text, 'lxml')#获取网页源代码
trs_temp = soup.find(id='comp_3805').find_all('tr')
再定位表格后,即可对tr内的内容进行定位,这里要注意的是trs_temp(即得到全部tr的soup型变量是从1开始计数,而不是从0开始计数的)
7. 提取文字内容
在定位到表格位置后,即可开始进行文字内容提取,首先对一页的表格文字进行提取,由于每一页的内容都有一个表头,并通过人工查阅,航天一院全部火箭发射记录有8页,因此没必要重复8次表头。
所以,只在读取第一页的时候,读取第一行信息作为表头:
# 填写表格的表头
Tags_title = trs_temp[1].find_all('td')
csv_writer.writerow(
[Tags_title[0].get_text().strip(),
Tags_title[1].get_text().strip(),
Tags_title[2].get_text().strip(),
Tags_title[3].get_text().strip(),
Tags_title[4].get_text().strip(),
Tags_title[5].get_text().strip()
])
print([Date,LV,Sat,JD,Times,Result],'表头填写完成')
在读取后续页码时(含读取第一页),采用统一的处理即可。另外观察到每一页的内容都是按照倒叙来统计的,即本文的第一条内容时间是最新发生的,最后一条内容是之前发生的。
因此,为了顺序排列,在开始进行持续性存储前,就对soup对象进行倒叙排列,排列方法为:
1. 首先去掉第一行表头;
2. 将剩余部分进行倒叙排列,源代码如下:
#定义数组
listData=[]
soup = BeautifulSoup(response.text, 'lxml')#获取网页源代码
trs_temp = soup.find(id='comp_3805').find_all('tr')
trs_re = trs_temp[2:len(trs)]
trs = trs_re[::-1]
发现soup类型也可以像列表和元组一样,进行切片处理和倒叙处理。真是方便和强大!
8. 持续性存储
进行持续性存储,将所有内容存储为csv格式。
csv文件的处理方法拢共分为3部:
1. 建立csv文件,并定义为写文件:f = open('D:/Data-SD/发射记录.csv','w',encoding='utf-8',newline='');csv_writer = csv.writer(f)
2. 刷刷向里写数据:csv_writer.writerow([Date,LV,Sat,JD,Times,Result])
3. 关闭csv文件:f.close()
贴上代码:
# 打开CSV文件
f = open('D:/Data-SD/发射记录.csv','w',encoding='utf-8',newline='')
csv_writer = csv.writer(f)
。。。
# 向文件中写数据
Title = trs[1].find_all('td')
Date = Title[0].get_text().strip()
LV = Title[1].get_text().strip()
Sat = Title[2].get_text().strip()
JD = Title[3].get_text().strip()
Times= Title[4].get_text().strip()
Result=Title[5].get_text().strip()
csv_writer.writerow([Date,LV,Sat,JD,Times,Result])
。。。
# 关闭文件
f.close()
最终得到的结果文件:
9. 异常处理
在程序编写的过程中,遇到了两个典型的问题,这里也一并写出来,供大家参考。
9.1 翻页URL不更新的处理方式
和处理豆瓣评分这种网络爬虫不同,在看航天一院的网站的时候,发现当翻页时,URL竟然没有变化!
后来查看了一些网上的处理方法后,找到了一条比较简单的处理方法:
按下F12对网页进行检查,将检查的项目选择Network->XHR,此时,再翻页的时候,发现有网络变化了,并得到了新的index:
显然啊,这里的index不完整,当把鼠标凑近时,发现了他的完整链接形式,
把以上连接直接输入到地址栏,发现果然可以直接访问,但是此时再看Elements发现本页的网络架构和之前看到的不同,因为一共有8页,所以当我一页一页点击过去后,发现2~8页对应index_3805_7~index_3805_1。而第一页是独特的一个地址。
好了,明确了之后就可以开始编程了:
1. 先建立一个str,并且每到一页,自动生成要给URL(更新index数据);
2. if判断如果是1~7页,就用程序化的URL,如果是8页就用原来的URL
9.2 CSV文件编写多一个空行的处理
在开始生成的CSV文件中,每两行中间都有一个空行,上网查了下,原来只需要在设置的时候将newline参数设置为空就可以。
f = open('D:/Data-SD/发射记录.csv','w',encoding='utf-8',newline='')
同时由于要写入中文,所以把encoding参数设置为'utf-8'
10. 小结
终于在自己的努力下,从零基础真正自己完成了一次爬虫。爬完后感觉内心空落落的,下一步就是要对这个数据进行分析了,需要使用pandas和matplotlib库,欢迎大家点赞、关注和支持。