实验十 网络爬虫
一、实验学时:2学时
二、实验目的
- 了解常用的HTML标签
- 了解在网页中使用JavaScript代码的几种方式
- 掌握Python标准库urllib的用法
- 掌握Python扩展库scrapy的用法
- 掌握Python扩展库BeautifulSoup4的用法
- 掌握Python扩展库request的用法
- 掌握Python扩展库selenium的用法
三、实验内容
编写爬虫程序实现下述各题。
- 批量爬取中国工程院院士信息,把每位院士的文字介绍保存到该院士名字为名的记事本文件中,照片保存到该院士名字为名的jpg文件中。
- 根据院士名单,爬取该院士性别,族别信息;根据院士简介提取该院士就读本科学校,入选院士年份;将院士姓名,性别,族别信息,本科学校,入选院士年份信息写入excel文件。
四、实验结果
-
批量爬取中国工程院院士信息,把每位院士的文字介绍保存到该院士名字为名的记事本文件中,照片保存到该院士名字为名的jpg文件中。
题目思路:通过爬取http://www.cae.cn/cae/html/main/col48/column_48_1.html 中国工程院网站获取中国工程院院士信息,首先在进入该页面后可以通过正则表达式获取所有院士对应的链接,进入链接中以后分别利用正则表达式去获取院士的图片和介绍,然后保存到文件即可。
程序代码:
""" 程序名:实验10.1.py 功能:批量爬取中国工程院院士信息,把每位院士的文字介绍保存到该院士名字为名的记事本文件中,照片保存到该院士名字为名的jpg文件中。 日期:2022.6.13 版本:1.0 """ import re from urllib.request import urlopen import requests my_url = r'http://www.cae.cn/cae/html/main/col48/column_48_1.html' # 中国工程院院士网站 r = requests.get(my_url) # 获取网站文本 pattern = r'<li class="name_list"><a href="(.+)" target="_blank">(.+)</a></li>' # 括号中为每一个院士对应的链接和姓名 a = re.findall(pattern, r.text) # 使用正则表达式查找超链接和姓名 for i in a: url2, name = i every_url = 'https://www.cae.cn/' + url2 # 院士链接需要加前缀 r2 = requests.get(every_url) # 获取院士网站文本 pattern1 = r'<img src="/cae/admin/upload/img/(.+)" style=' # 括号中为每个院士对应的图片文件名 result = re.findall(pattern1, r2.text, re.I) # 使用正则表达式查找院士图片链接 picUrl = r'https://www.cae.cn/cae/admin/upload/img/' + result[0] # 院士图片链接需要加前缀 picUrl = picUrl.replace(' ', '%20') # 部分院士链接中含有空格,无法识别需要转换成%20 with open(name + '.jpg', 'wb') as fp: fp.write(urlopen(picUrl).read()) pattern2 = '<div class="intro">(.*?)</div>' result2 = re.findall(pattern2, r2.text, re.S) # # re.S匹配换行的 result3 = re.sub(r'<p>| | |</p>', '', result2[0]).strip() # .strip()清楚空格 with open(name + '.txt', 'w', encoding='utf-8') as fp: fp.write(str(result3))
运行结果截图:
-
根据院士名单,爬取该院士性别,族别信息;根据院士简介提取该院士就读本科学校,入选院士年份;将院士姓名,性别,族别信息,本科学校,入选院士年份信息写入excel文件。
题目思路:与上次类似,在单个院士链接中通过特定的正则表达式获取对应信息,然后分别存储到5个列表中,然后根据这五个列表去创建对应的二维数组,通过DataFrame建表,然后保存到excel文件xlsx中即可。
程序代码:
""" 程序名:实验10.2.py 功能:根据院士名单,爬取该院士性别,族别信息; 根据院士简介提取该院士就读本科学校,入选院士年份; 将院士姓名,性别,族别信息,本科学校,入选院士年份信息写入excel文件。 日期:2022.6.13 版本:1.0 """ import re from urllib.request import urlopen import requests import numpy as np import pandas as pd name = [] sex = [] nation = [] undergraduate = [] time = [] my_url = r'http://www.cae.cn/cae/html/main/col48/column_48_1.html' # 中国工程院院士网站 r = requests.get(my_url) # 获取网站文本 pattern = r'<li class="name_list"><a href="(.+)" target="_blank">(.+)</a></li>' # 括号中为每一个院士对应的链接和姓名 a = re.findall(pattern, r.text) # 使用正则表达式查找超链接和姓名 for i in a: # 姓名 url2, name1 = i every_url = 'https://www.cae.cn/' + url2 # 院士链接需要加前缀 r2 = requests.get(every_url) b = re.findall('<div class="cms_ysg_title"><a href="(.+)" target="_blank">(.+)</a></div>', r2.text) url3 = b[0][0] r3 = requests.get(url3) # 性别 c = re.findall('<div><h4 class="row">性别</h4><span>:</span><h4>(.+?)</h4></div>', r3.text) if c == []: c = re.findall('<div><h4 class="text_justify">性别</h4><span>:</span>(.+?)</div>', r3.text) if c != []: c = c[0] if c == []: c = '未知' # 族别信息 d = re.findall('<div><h4 class="row">民族</h4><span>:</span><h4>(.+?)</h4></div>', r3.text) if d == []: d = re.findall('<div><h4 class="text_justify">民族</h4><span>:</span>(.+?)</div>', r3.text) if d != []: d = d[0] if d == []: d = '未知' # 本科学校 e = re.findall('毕业于(.*?)[,|。]', r2.text) if e == []: e = re.findall('[>()](.+?)大学', r3.text) if e != []: e = e[0] else: e = e[0] if e == []: e = '未知' # 入选院士年份 f = re.findall('\d{1,4}年当选', r2.text) if f != []: f = f[0].replace('当选', '') if f == []: f = '未知' name.append(name1) sex.append(c) nation.append(d) undergraduate.append(e) time.append(f) print(name1) data = np.array([name, sex, nation, undergraduate, time]) data = data.T frame = pd.DataFrame(data=data, index=range(1, len(name) + 1), columns=['姓名', '性别', '族别信息', '本科学校', '入选院士年份']) frame.to_excel('中国工程院院士信息.xlsx') print("完成")
运行结果截图:
五、实验小结
问题与解决方法:
-
使用正则表达式获取的链接程序无法打开,但是在网页中点击可以打开。
解决方法:获取的链接缺少前缀,在网页中没有该前缀也能打开。需要通过字符串方法进行拼接。
-
在正则表达式中含有换行符,无法正确读取。
解决方法:通过re.S可以设置匹配的模式,re.S代表使 . 匹配包括换行在内的所有字符。
-
部分院士链接中含有空格,程序无法识别。但是在网页中可以正常打开。
解决方法:URL中统一使用%20来编码空格字符。因此需要利用字符串方法replace()将URL中的空格替换成为%20。
-
写入.xls文件时报错:FutureWarning: As the xlwt package is no longer maintained, the xlwt engine will be removed in a future version of pandas . This is the only engine in pandas that supports writing in the xls format. Install openpyxl and write to an xlsx file instead. You can set the option io.excel.xls.writer to ‘xlwt’ to silence this warning. While this option is deprecated and will also raise a warning, it can be globally set and the warning suppressed. data.to_excel(save_file_path)
解决方法:翻译过来就是由于xlwt软件包不再维护,xlwt引擎将在未来版本的pandas中删除。这是pandas中唯一支持xls格式写入的引擎。安装openpyxl并改为写入xlsx文件。您可以设置选项io.excel.xls文件。写入“xlwt”以消除此警告。虽然此选项已弃用,并且还会引发警告,但可以全局设置它并抑制警告。因此可以将.xls文件改成.xlsx即可正常保存。
心得体会:
- python爬虫是一个很好用的方法,在自己一开始学习的时候也不明白为什么要出现“爬虫“这样的东西,明明可以直接自己打开网页下载和浏览,但是后来一想,如果有翻页就可以按照规则爬完了一页就解析另外一页HTML,也就是说,只要掌握的爬取方法,无论工作量有多么大都可以按我们的心思去收集想要的数据。这就是爬虫的强大之处,可以批量爬取许多我们生活中需要下载的网页中的东西。