数据采集与融合技术第一次实践
第一次大作业
作业①
-
要求:用urllib和re库方法定向爬取给定网址(https://www.shanghairanking.cn/rankings/bcsr/2020/0812 )的数据。
-
输出信息:
2020排名 全部层次 学校类型 总分 1 前2% 中国人民大学 1069.0 2... (1)实现过程:
-
用urlib爬取网页信息:
req = urllib.request.Request(url, headers=headers) data = urllib.request.urlopen(req) data = data.read() dammit = UnicodeDammit(data, ["utf-8", "gbk"]) data = dammit.unicode_markup return data # 获取文本信息
-
re正则式查取所需信息
# 当字符串中含有\n和空格时,re正则很难正确匹配到我们想要的数字,所以用replace函数将其替换。 data = data.replace("\n", "").replace(" ", "") rank = re.findall(r'<divclass="ranking"data-v-68e330ae>(\d*)</div>', data) level = re.findall(r'<tddata-v-68e330ae>(前\d*%)<!----></td>', data) style = re.findall(r'imgalt="(.*?)"onerror=\'this.src="/images/blank.svg"\'', data) score = re.findall(r'<tddata-v-68e330ae>([1-9]\d*\.?\d*)', data)
-
主函数:
url = "https://www.shanghairanking.cn/rankings/bcsr/2020/0812" data = getHTMLText(url) tplt = "{0:^10}\t{1:{4}^14}\t{2:{4}^20}\t{3:^10}" # 中西文混排时,要使用中文字符空格填充chr(12288) print(tplt.format('2020排名', '全部层次', '学校类型', '总分', chr(12288))) rank, level, style, score = fillUnivList(data) for i in range(len(rank)): print(tplt.format(rank[i], level[i], style[i], score[i], chr(12288)))
-
结果展示:
(2)心得体会:
作业①主要考察了urlib爬取网页的方法和re正则表达式的灵活运用,主要包含以下几个难点:
-
对爬取得到的data进行分析(红色部分为我们想要的数据)
可以发现“\n”与一连串的空格使得我们使用re定位数据变的困难,所以我们可以将data(字符串类型)中的回车符与空格删除。
当然,这也意味着在接下来的re正则表达式中,注意删除空格。 -
对输出结果进行对齐处理,这就要用到中文字符空格填充函数chr(12288)。
-
作业②
-
要求:用requests和Beautiful Soup库方法设计爬取(https://datacenter.mee.gov.cn/aqiweb2/ )AQI实时报。
-
输出信息:
序号 城市 AQI PM2.5 SO2 No2 Co 首要污染物 1 北京 55 6 5 1.0 225 —— 2... (1)实现过程:
-
用requests爬取网页:
r = requests.get(url, headers=headers, timeout=30) r.raise_for_status() r.encoding = r.apparent_encoding r.encoding = 'gbk' # 将内容解码用gbk return r.text
-
Beautiful Soup库方法查找包含城市信息的tr节点,select寻找所需信息:
soup = BeautifulSoup(data, "lxml") citys = soup.select("tbody tr") for city in citys: name = city.select("td")[0].text # 获取文本信息 AQI = city.select("td")[1].text PM2 = city.select("td")[2].text S02 = city.select("td")[4].text N02 = city.select("td")[5].text CO = city.select("td")[6].text pri_pollut = city.select("td")[8].text
-
打印,用i+=1作为序号:
tplt = "{0:^5}\t{1:{8}^10}\t{2:{8}^5}\t{3:{8}^5}\t{4:{8}^6}\t{5:{8}^5}\t{6:{8}^5}\t{7:{8}^6}"
print(tplt.format(i, name.strip(), AQI.strip(), PM2.strip(), S02.strip(), N02.strip(), CO.strip(), pri_pollut.strip(), chr(12288)
-
结果展示:
(2)心得体会:
作业②主要用requests进行网页信息爬取,Beautiful Soup解析为lxml, css算法查找所需信息。有两个细节:
- requests的编码形式要设成‘gbk’,防止出现中文乱码
- 从下图可以看出,想要查找的信息很容易找到,都在td节点下。
- 由于这个网页是动态页面,所以会出现以下情况:
-
作业③
-
要求:使用urllib和requests爬取(http://news.fzu.edu.cn),并爬取该网站下的所有图片
-
输出信息:将网页内的所有图片文件保存在一个文件夹中
(1)实现过程:
-
requests爬取网页:
r = requests.get(url, headers=headers, timeout=30) r.raise_for_status() r.encoding = r.apparent_encoding return r.text
-
re寻找图片地址链接:
image = re.findall(r'img src="(.*?)"', data)
-
保存图片到本地:
''' 函数功能:保存图片到本地 参数说明: image:图片地址集 url : 网页地址 path : 存储路径 ''' def save_image(image, url, path): for j in range(0, len(image)): img = image[j] imgurl = url + img # 将url与图片地址拼接得到完整的图片地址url imgName = imgurl.split('/')[-1] # 截取图片地址的最后一段作为图片名称 urllib.request.urlretrieve(imgurl, r'{}\{}'.format(path, imgName))
-
结果展示
(2)心得体会:
作业三主要实现下载网络上的图片。
主要就是查找图片的地址链接:
re.findall(r'img src="(.*?)"', data)就可实现。
附:完整代码地址 -