通过爬虫程序的编写,进一步理解HTTP协议。用conda建立一个名为crawler的python虚拟环境,在此虚拟环境中用pip或conda安装requests、beautifulsoup4等必要包(若有网络问题,请切换国内镜像网站或国外网站仓库,注意两个安装工具使用不同的仓库)。当使用jupyter、pycharm、spyder、vscoder等IDE编程环境时,需要自己选择设置IDE后台使用的python版本或虚拟环境。比如当使用jupyter notebook时,参考(https://blog.csdn.net/qq_35654046/article/details/106972448),在jupyter运行的web界面中选择对其应的python内核Kernel(有虚拟环境列表);如果使用pycharm,参考(https://blog.csdn.net/ifubing/article/details/105153541)选择相应的已有虚拟环境。
爬虫内容:
1)编程完成对南阳理工学院ACM题目网站 http://www.51mxd.cn/ 练习题目数据的抓取和保存;
2)改写爬虫代码,将重庆交通大学新闻网站中近几年所有的信息通知(http://news.cqjtu.edu.cn/xxtz.htm) 的发布日期和标题全部爬取下来,并写到CSV电子表格中。
网站上的发布日期和标题 格式示例如下所示:
“2021-10-28;城市轨道车辆系统集成与控制重庆市重点实验室 2021 年度开放基金申报指南
2021-10-28;公共交通装备设计与系统集成重庆市重点实验室2021年度开放基金申报通知
2021-10-28;关于组织2021年新入职教师参观科学城校区实验平台的通知”
嘿!我是目录
一、爬虫介绍
1.1 网络爬虫简介
- 网络爬虫,也叫网络蜘蛛(Web Spider)。它根据网页地址(URL)爬取网页内容,而网页地址(URL)就是我们在浏览器中输入的网站链接。
例如:https://www.baidu.com
- URL 专业一些的叫法是统一资源定位符(Uniform Resource Locator),它的一般格式如下(带方括号[]的为可选项):
protocol :// hostname[:port] / path / [;parameters][?query]#fragment
- URL 的格式主要由前个三部分组成:
protocol:第一部分就是协议,例如百度使用的就是https协议;
hostname[:port]:第二部分就是主机名(还有端口号为可选参数),一般网站默认的端口号为80,例如百度的主机名就是www.baidu.com,这个就是服务器的地址;
path:第三部分就是主机资源的具体地址,如目录和文件名等。
网络爬虫就是根据这个 URL 来获取网页信息的。
- 还是,以百度为例,举个简单的例子:
http://www.baidu.com:80
https://www.baidu.com:443
这两个 URL 都可以打开网页,区别在于一个是 http 协议,一个是 https 协议。
http 协议默认使用的端口是 80,https 协议默认使用的端口是 443。
每一个 URL 的背后,其实都是对应着一台服务器的,甚至成千上万台。
通俗一点讲,URL 就是每个服务器的地址。
1.2 审查元素
- 在爬虫之前,我们需要先学习一项写爬虫的必备技能:审查元素。
- 在浏览器的地址栏输入 URL 地址,在网页处右键单击,找到检查。(不同浏览器的叫法不同,Chrome 浏览器叫做检查,Firefox 浏览器叫做查看元素,但是功能都是相同的)
我们可以看到,下方(不同电脑出现的地方可能不一样)出现了一大推代码,这些代码就叫做 HTML 。什么是 HTML ?举个容易理解的例子:我们的基因决定了我们的原始容貌,服务器返回的 HTML 决定了网站的原始容貌。
1.3 网页搜索策略
网页的抓取策略可以分为深度优先、广度优先和最佳优先三种。深度优先在很多情况下会导致爬虫的陷入(trapped)问题,目前常见的是广度优先和最佳优先方法。
- 广度优先搜索
广度优先搜索策略是指在抓取过程中,在完成当前层次的搜索后,才进行下一层次的搜索。该算法的设计和实现相对简单。在目前为覆盖尽可能多的网页,一般使用广度优先搜索方法。也有很多研究将广度优先搜索策略应用于聚焦爬虫中。其基本思想是认为与初始URL在一定链接距离内的网页具有主题相关性的概率很大。另外一种方法是将广度优先搜索与网页过滤技术结合使用,先用广度优先策略抓取网页,再将其中无关的网页过滤掉。这些方法的缺点在于,随着抓取网页的增多,大量的无关网页将被下载并过滤,算法的效率将变低。 - 最佳优先搜索
最佳优先搜索策略按照一定的网页分析算法,预测候选URL与目标网页的相似度,或与主题的相关性,并选取评价最好的一个或几个URL进行抓取。它只访问经过网页分析算法预测为“有用”的网页。存在的一个问题是,在爬虫抓取路径上的很多相关网页可能被忽略,因为最佳优先策略是一种局部最优搜索算法。因此需要将最佳优先结合具体的应用进行改进,以跳出局部最优点。将在第4节中结合网页分析算法作具体的讨论。研究表明,这样的闭环调整可以将无关网页数量降低30%~90%。 - 深度优先搜索
深度优先搜索策略从起始网页开始,选择一个URL进入,分析这个网页中的URL,选择一个再进入。如此一个链接一个链接地抓取下去,直到处理完一条路线之后再处理下一条路线。深度优先策略设计较为简单。然而门户网站提供的链接往往最具价值,PageRank也很高,但每深入一层,网页价值和PageRank都会相应地有所下降。这暗示了重要网页通常距离种子较近,而过度深入抓取到的网页却价值很低。同时,这种策略抓取深度直接影响着抓取命中率以及抓取效率,对抓取深度是该种策略的关键。相对于其他两种策略而言。此种策略很少被使用。
二、Anaconda 环境配置
- 打开Anaconda Prompt
- 创建虚拟环境(crawler是环境名,可自行更改,python=2.7是下载的python版本,也可自行更改)
conda create -n pythonwork python=2.7
- 激活环境
activate crawler
- 在此虚拟环境中用pip或conda安装requests、beautifulsoup4等必要包。
conda install -n crawler requests
conda install -n crawler beautifulsoup4
conda install tqdm
- 然后打开anaconda可以看见我们刚刚创建的虚拟环境,安装下载Spyder:
- 打开Spyder
- 页面功能:
三、实例1:对南阳理工学院ACM题目网站进行抓取和保存
3.1 网址
3.2 实验代码
- 代码:
import requests
from bs4 import BeautifulSoup
import csv
from tqdm import tqdm
# 模拟浏览器访问
Headers = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400'
# 表头
csvHeaders = ['题号', '难度', '标题', '通过率', '通过数/总提交数']
# 题目数据
subjects = []
# 爬取题目
print('题目信息爬取中:\n')
for pages in tqdm(range(1, 11 + 1)):
r = requests.get(f'http://www.51mxd.cn/problemset.php-page={pages}.htm', Headers)
r.raise_for_status()
r.encoding = 'utf-8'
soup = BeautifulSoup(r.text, 'html.parser')
td = soup.find_all('td')
subject = []
for t in td:
if t.string is not None:
subject.append(t.string)
if len(subject) == 5:
subjects.append(subject)
subject = []
# 存放题目
with open('NYOJ_Subjects.csv', 'w', newline='') as file:
fileWriter = csv.writer(file)
fileWriter.writerow(csvHeaders)
fileWriter.writerows(subjects)
print('\n题目信息爬取完成!!!')
- 新建一个文件,直接添加到其中:
3.3 实验结果
- 打开生成的.csv文件:
NYOJ_Subjects.csv
四、实例2:抓取重交大新闻网站中近几年所有的信息通知时间和标题
4.1 网址
网页底部可以看见所有消息共有66个页面,要爬取所有新闻就要知道这些页面的地址,点击下一页可以看见网页链接中如:http://news.cqjtu.edu.cn/xxtz/1.htm有一个数字根据页面数变化,且除首页外,其余页面中的数字都是67-该页面底部页面数。我们可以用一个简单的循环得到这些页面链接中的数字。
4.2 实验代码
# -*- coding: utf-8 -*-
"""
Created on Sun Nov 14 21:17:21 2021
@author: hp
"""
import requests
from bs4 import BeautifulSoup
import csv
from tqdm import tqdm
# 模拟浏览器访问
Headers ={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.44'}
#csv的表头
cqjtu_head=["日期","标题"]
#存放内容
cqjtu_infomation=[]
#获取新闻标题和时间
def get_time_and_title(page_num,Headers):#页数,请求头
if page_num==66 :
url='http://news.cqjtu.edu.cn/xxtz.htm'
else :
url=f'http://news.cqjtu.edu.cn/xxtz/{page_num}.htm'
r=requests.get(url,headers=Headers)
r.raise_for_status()
r.encoding="utf-8"
array={#根据class来选择
'class':'time',
}
title_array={
'target':'_blank'
}
page_array={
'type':'text/javascript'
}
soup = BeautifulSoup(r.text, 'html.parser')
time=soup.find_all('div',array)
title=soup.find_all('a',title_array)
temp=[]
for i in range(0,len(time)):
time_s=time[i].string
time_s=time_s.strip('\n ')
time_s=time_s.strip('\n ')
#清除空格
temp.append(time_s)
temp.append(title[i+1].string)
cqjtu_infomation.append(temp)
temp=[]
# 爬取题目
print('新闻信息爬取中:\n')
for pages in tqdm(range(66, 0,-1)):
get_time_and_title(pages,Headers)
# 存放题目
with open('cqjtu_news.csv', 'w', newline='') as file:
fileWriter = csv.writer(file)
fileWriter.writerow(cqjtu_head)
fileWriter.writerows(cqjtu_infomation)
print('\n新闻信息爬取完成!!!')
4.3 实验结果
- 打开生成的.csv文件:
cqjtu_news.csv
小小的总结
这篇文章的爬虫只是简单获取的列表,没有获取列表里链接里的内容。
网络爬虫通过使用http请求的用户代理(User Agent)字段来向网络服务器表明他们的身份。网络管理员则通过检查网络服务器的日志,使用用户代理字段来辨认哪一个爬虫曾经访问过以及它访问的频率。用户代理字段可能会包含一个可以让管理员获取爬虫更多信息的URL。邮件抓取器和其他怀有恶意的网络爬虫通常不会留任何的用户代理字段内容,或者他们也会将他们的身份伪装成浏览器或者其他的知名爬虫。
有时候在第二遍运行爬虫的时候,发现获取不到信息;这时候我们需要改变模拟浏览器再去访问。