【数据采集】第一次实验
1. 作业①
1.1 题目
用
urllib
和re
库方法定向爬取给定网址的数据
1.2 思路
1.2.1 发送请求
- 引入库并且编写请求头
请求头是为了把爬虫包装成浏览器的正常访问。
import urllib.request
import re
header = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36',
}
urllib
和requests
不同
urllib构造请求头
和发送请求
是分开的,而requests是封装在一起的。
url = "https://www.shanghairanking.cn/rankings/bcsr/2020/0812"
request = urllib.request.Request(url, headers=header) # 构造请求头
r = urllib.request.urlopen(request) # 发送请求
1.2.2 解析网页
- decode() 是为了解码成
中文
- replace('\n','') 是为了把回车去掉,方便后续的正则匹配。
html = r.read().decode().replace('\n','')
1.2.3 获取结点
- 分析网页
我们很容易找到结点信息,然后观察节点信息的结构。
- 使用正则表达式获取总体的节点信息
ranking = re.findall("<td data-v-68e330ae>(.*?)</td></tr>",html)
- 构造字典来存储数据
uList =[]
for k in ranking:
u = {
"rank":"",
"percent":"",
"name":"",
"socre":"",
}
name = re.findall("img alt=(.*?) onerror",k)
# 匹配出名字
ranking = re.findall(" (\d+) ",k)
# 匹配出排名
socre = re.findall("<td data-v-68e330ae> (.*?) ",k)
# 匹配出分数
u["rank"]=ranking[0]
u["percent"]=socre[0]
u["name"]=eval(name[0])
u["socre"]=socre[1]
uList.append(u)
1.2.4 数据输出
print("2020排名\t全部层次\t学校类型\t\t总分")
for u in uList:
print("{}\t\t{}\t\t{}\t\t{}\t\t".format(u["rank"],u["percent"],u["name"],u["socre"]))
2. 作业②
2.1 题目
用
requests
和Beautiful Soup
库方法设计爬取网址的AQI实时报
2.2 思路
2.2.1 发送请求
- 导入库
import requests
from bs4 import BeautifulSoup
- 构造请求头
headers = {
'Connection': 'keep-alive',
'sec-ch-ua': '"Chromium";v="94", "Google Chrome";v="94", ";Not A Brand";v="99"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Sec-Fetch-Site': 'none',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-User': '?1',
'Sec-Fetch-Dest': 'document',
'Accept-Language': 'zh-CN,zh;q=0.9',
}
- 发送请求
response = requests.get('https://datacenter.mee.gov.cn/aqiweb2/', headers=headers)
2.2.2 解析网页
- 使用
BeautifulSoup
解析器进行解析,解析成lxml
格式
soup = BeautifulSoup(response.content,"lxml")
解析器的作用是为了把请求到的字符串
重新解析成lxml前端树
的格式,方便获取器
进行节点的Find
等操作。
2.2.3 获取结点
- 分析网页
我们可以看到我们所想要的节点信息都是在这个在td
标签下的,所以我们只需要找到所有的td
标签即可。
- 找到所有的
td
tdTmp = soup.find_all('td')
结果我们打印结果,我们发现,数据除了text格式之后,还可能存在\t\n\r
这些空格,所以要进行一个清洗替换
- 数据清洗
把\r\t\n
这些空格回车字符进行清洗替换
for i in range(len(tdTmp)):
info=tdTmp[i].text
if len(info)>10:
info = info.replace('\r', '')
info = info.replace('\n', '')
info = info.replace('\t', '')
somethingList.append(info)
if count < 8:
count += 1
td.append(info)
else:
tds.append(td)
count=0
td = []
2.2.4 数据输出
一样采用字典键值对
去存储数据。
num=0
for td in tds:
cityWeather={
"num":"",
"city":"",
"AQI":"",
"PM2.5":"",
"So2":"",
"No2":"",
"Co":"",
"something":"",
}
cityWeather["num"]=num+1
cityWeather["city"]=td[0]
cityWeather["AQI"]=td[1]
cityWeather["PM2.5"]=td[2]
cityWeather["So2"]=td[4]
cityWeather["No2"]=td[5]
cityWeather["Co"]=td[6]
cityWeather["something"]=somethingList[num]
num+=1
infoList.append(cityWeather)
print(cityWeather)
结果输出
print("序号 \t 城市 \t\t AQI \t PM2.5 \t So2 \t Co \t 首要污染物")
for k in infoList:
print("{} \t {} \t {} \t {} \t {} \t {} \t {}".format(k["num"],k["city"],k["AQI"],k["PM2.5"],k["So2"],k["Co"],k["something"]))
3. 作业③
3.1 题目
要求:使用urllib和requests和re爬取一个给定网页
爬取该网站下的所有图片
输出信息:将自选网页内的所有jpg文件保存在一个文件夹中
3.2 思路
3.2.1 发送请求
- 引入库
import requests,re
import urllib
- 构造请求头
headers = {
'Connection': 'keep-alive',
'Cache-Control': 'max-age=0',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Accept-Language': 'zh-CN,zh;q=0.9',
}
url = 'http://news.fzu.edu.cn/'
- 发送请求
urllib
:
request = urllib.request.Request(url, headers=headers)
r = urllib.request.urlopen(request)
requests
:
response = requests.get(url, headers=headers, verify=False)
3.2.2 解析网页
urllib
:
html = r.read().decode().replace('\n','')
requests
:
html = response.content().replace('\n','')
3.2.3 获取结点
- 注意一点
img
和src
之间也可能会有匹配的,所以不能直接使用<img src="(.*?)
这种形式的正则。
- 正则匹配出所有的图片信息
imgList = re.findall(r'<img.*?src="(.*?)"', html, re.S)
3.2.4 数据输出
- 创建一个文件夹image进行保存
for i, img in enumerate(imgList):
img_url = "http://news.fzu.edu.cn" + img
print(f"正在保存第{i + 1}张图片 路径:{img_url}")
resp = requests.get(img_url)
with open(f'./image/{img.split("/")[-1]}', 'wb') as f:
f.write(resp.content)
代码地址
gitee:https://gitee.com/cocainecong/spider-experiment
最后
- 本次实验做的有点仓促,主要是正则使用的不够熟练。
- 还有就是平时都是用
requests
进行爬虫,虽然urllib
也有用,但是不熟,通过这次实验,也算是对urllib和正则有了一定的熟悉