(1)实现对新闻网页前10页url的爬取,初始的网页url种子为https://news.qut.edu.cn/zhxw.htm,构建pageUrl列表对象对获取到的url进行存储(url要通过页面的“上一页”或“下一页”链接获得,获取5个新闻页面url);构建pageUrlCrawled列表对象存储已经爬取的新闻网页url。
① 代码:
import requests
import re
pageurl = []
# 请求网页内容
def get_url(url):
requests.packages.urllib3.disable_warnings()
# 有的网站,需要SSL证书验证,若没有设置SSL会报错,所忽略报错
r = requests.get(url, verify=False, timeout=2)
# get向服务器请求数据,时间间隔为2
r.encoding = r.apparent_encoding # 为了正确编码数据
return r # 返回网页内容
# 取到当前url中下页的url,直到取了my_cnt个
def curcal_get_url(url, cnt):
url_list = [] # my_url列表存放获取的所有url
while cnt:
# 将当前的url添加到my_url列表中
# 未放到最后再添加是因为写到最后会将第一个给漏掉
url_list.append(url)
r = get_url(url)
pattern = r'<a href="([\S]+.htm)" class="Next">下页</a>'
info = re.findall(pattern, r.text)
# 因为得到的是相对路径,所以要变为绝对路径
# 青理首页url格式和后面的不一样所以要单独判断
if cnt == 5:
url = "https://news.qut.edu.cn/" + info[0]
else:
url = "https://news.qut.edu.cn/zhxw/" + info[0]
cnt = cnt - 1
return url_list
if __name__ == "__main__":
seed = "https://news.qut.edu.cn/zhxw.htm"
my_cnt = 5
pageurl = curcal_get_url(seed, my_cnt)
print(pageurl)
(2)构建BloomFilter对象对新获取的url是否已存在于pageUrlCrawled列表中进行判断,如果不存在则将该url添加pageUrl列表对象中,否则不添加该url。获取完所有的url后,分析url数据存在的问题并设计可行的数据预处理方案。最后,对pageUrl列表对象中存储的url数据进行处理。
① 代码:
import requests
import re
from pybloom_live import ScalableBloomFilter
pageurl = []
# 创建了一个初始容量为 100,错误率为 0.01 的可扩展布隆过滤器对象 bloom
bloom = ScalableBloomFilter(initial_capacity=100, error_rate=0.01)
# 请求网页内容
def get_url(url):
requests.packages.urllib3.disable_warnings()
# 有的网站,需要SSL证书验证,若没有设置SSL会报错,所忽略报错
r = requests.get(url, verify=False, timeout=2)
# get向服务器请求数据,时间间隔为2
r.encoding = r.apparent_encoding # 为了正确编码数据
return r # 返回网页内容
# 取到当前url中下页的url,直到取了my_cnt个
def curcal_get_url(url, cnt):
url_list = [] # my_url列表存放获取的所有url
while cnt:
# 第一次bloom为空,所以会将当前的url加入到bloom中,
# 因而在这之后的url都会与前面所有添加进去的url进行比较是否在里面,达到去重的目的。
if url in bloom:
continue
else:
bloom.add(url)
# 将当前的url添加到my_url列表中
# 未放到最后再添加是因为写到最后会将第一个给漏掉
url_list.append(url)
r = get_url(url)
pattern = r'<a href="([\S]+.htm)" class="Next">下页</a>'
info = re.findall(pattern, r.text)
# 因为得到的是相对路径,所以要变为绝对路径
# 青理首页url格式和后面的不一样所以要单独判断
if cnt == 5:
url = "https://news.qut.edu.cn/" + info[0]
else:
url = "https://news.qut.edu.cn/zhxw/" + info[0]
cnt = cnt - 1
return url_list
if __name__ == "__main__":
seed = "https://news.qut.edu.cn/zhxw.htm"
my_cnt = 5
pageurl = curcal_get_url(seed, my_cnt)
print(pageurl)
(3)读取PageUrl列表对象,对于请求到的每个新闻网页数据,使用BeautifulSoup进行网页数据的解析,提取每个新闻的标题、对应的正文页面URL和发布日期;要求爬取每个网页的时间间隔为2秒。将从网页中解析到的新闻数据保存到Csv或txt文本文件中进行存储,每行存储一个新闻数据。
① 代码:
import requests
import re
from pybloom_live import ScalableBloomFilter
from bs4 import BeautifulSoup
pageurl = [] # 全局变量
bloom = ScalableBloomFilter(initial_capacity=100, error_rate=0.01)
def get_url(x):
requests.packages.urllib3.disable_warnings()
# 有的网站,需要SSL证书验证,若没有设置SSL会报错,所忽略报错
r = requests.get(x, verify=False, timeout=2)
# 向服务器请求数据,时间间隔为2
r.encoding = r.apparent_encoding
# 正确编码数据
return r
def curcal_get_url(seed, cnt):
url1 = [] # 局部变量
while cnt:
if seed in bloom:
continue
else:
bloom.add(seed)
url1.append(seed) # 将获取的url添加到url1列表里
r = get_url(seed)
pattern = r'<a href="([^"]+\.htm)" class="Next">下页<\/a>'
newsInfo = re.findall(pattern, r.text)
if cnt == 5: # 青理首页url格式和后面的不一样所以要单独判断
seed = "https://news.qut.edu.cn/" + newsInfo[0]
else:
seed = "https://news.qut.edu.cn/zhxw/" + newsInfo[0]
cnt = cnt - 1
return url1
def get_info(x): # 用来获取标题链接和时间
newsdata = []
r = get_url(x)
soup = BeautifulSoup(r.text, "html.parser")
newslevel = soup.find_all('ul') # 通过soup对象获取<ul>标签内的数据
for news in newslevel:
newslevel2 = news.find_all('li', id=re.compile("line_u6_\d"))
for news in newslevel2:
newshrefinfo = news.a['href']
newstimeinfo = news.span.string
newsdata.append([news.a.string, 'https://news.qut.edu.cn/'+newshrefinfo[-19:], newstimeinfo])
return newsdata
if __name__ == "__main__":
seed = "https://news.qut.edu.cn/zhxw.htm"
cnt = 5
pageurl = curcal_get_url(seed, cnt)
# print(pageurl)
with open('output1.txt', 'w') as file:
for i in pageurl:
url = i
news1 = get_info(url)
for title, href, time in news1:
file.write(f'标题:{title}\n')
file.write(f'链接:{href}\n')
file.write(f'时间:{time}\n')
print(f'{url}已爬取完毕')
print("文件已爬取完毕")