一、简介
本文介绍的是一种初级的基于python包(beautifulSoup 简称BS4)的针对网页文本(html文本)的解析、抓取数据方法
需要知识:简单的python语言,简单的了解html及其标签名称、关系。
代码简陋,尚未结构化,模块化,希望大家不吝赐教(#^.^#)
二、目标
爬取浙大宁波理工学院>理工新闻>理工要闻的所有文章的 标题、写作日期、正文,并输出为Excel表格
三、工具
1、python(本机version3.83)
2、Python包详情看代码
3、Python的ide(Integrated development environment集成开发环境本机pycharm2019.2.5)
四、流程
1、分析:观察目标网页
发现“理工要闻”下有共有81个文章导航页面,这些文章导航页面下都存在文章的链接,且文章导航页面的url
(Uniform Resource Locator)皆是形如:
http://www.nit.net.cn/lgxw/lgyw.htm
http://www.nit.net.cn/lgxw/lgyw/80.htm
所以有想法:
1、先获得所有文章导航页面的url
2、后将每个文章导航页面的url解析,获取在导航页面上的文章链接
3、再将获取到的文章链接进行解析,分别获取文章标题、文章书写日期、文章正文
4、最后用输出流写为Excel文件。
五、代码
除去注释共87行
'''
任务目标:从浙大宁波理工学院网上爬取所有新闻标题,内容,日期,放入一张Excel表中
任务方法:
1、先获取不同页面的html
2、再从中找出具体文章链接
3、再进入具体文章链接,获取具体文章的HTML
4、解析html获取目标信息
5、保存信息并导出
@Aliang
2020/11/26
'''
'''
获取目标页面链接
页面形如
http://www.nit.net.cn/lgxw/lgyw/1.htm
http://www.nit.net.cn/lgxw/lgyw.htm
'''
import re
import requests
from bs4 import BeautifulSoup
from bs4 import SoupStrainer
import openpyxl
import sys
import time
import urllib
import os,sys,io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030')
#上方语句用来处理输出流乱码问题
basUrl = 'http://www.nit.net.cn/lgxw/lgyw'
basUrlend = ".htm"
initial_arry_int = []
for i in range(1, 81):
initial_arry_int.append(i)
arry_str = [str(i) for i in initial_arry_int]
pageUrl_arry_str=[]
for i in range(0, 80):
pageUrl = basUrl + "/" + arry_str[i] + basUrlend
# print(pageUrl)测试语句
pageUrl_arry_str.append(pageUrl)
# print(pageUrl_arry_str)测试语句
#print(pageUrl_arry_str)测试语句
'''
上述方法是出学时对结构化的页面进行了解析,发现只要将
http://www.nit.net.cn/lgxw/lgyw+“/i”+.htm即可获得所有的文章导航页面
当然也可以用
'http://www.nit.net.cn/lgxw/lgyw/{}.htm'.format(i)
得到结构化的页面
'''
# ————————>获取到了不同页面的url,并置于pageUrl_arry_str中
linkArry=[]
count=0
for aimUrl in pageUrl_arry_str:
# print(aimUrl)
res = requests.get(aimUrl)
# 将获取的html用utf-8的方式解码
res.encoding = 'utf-8'
html=res.text
# print(html)
soup = BeautifulSoup(html, "html.parser")
for aimlink in soup.find_all(href=re.compile("/info/1013")):
linkArry.append(aimlink.get('href'))
count=count+1
print(count)#统计总共有多少文章链接
# ————————>获取到了不同页面文章的url的初始值,其url的值形如"../../info/1013/8910.htm"
pure_link_list=[]
# print(linkArry[1])
for i in range(1,count):
s=''
temp1=s.join(linkArry[i])
#因为split导致的情况是使得刚刚已经转化成的字符,变成了一个新的字符串
pureStr=temp1.split('../..')
temp2 = s.join(pureStr[1])
temp3="http://www.nit.net.cn"+temp2
pure_link_list.append(temp3)
print(pure_link_list)
# ————————>通过清洗获取到了所有的目标url并放入pure_link_list中,下一步进入目标url,获取正文和标题
paperArry=[]
dataArry=[]
titleArry=[]
for aimUrl in pure_link_list:
tempArry = []
res = requests.get(aimUrl)
res.encoding = 'utf-8'
html=res.text
html=html.replace('\r','')
#去掉原来html文档中自动换行标签
html=html.replace('\xa0','')
#去掉导致解析出现问题的特殊字符串,但是好像效果并不行
soup = BeautifulSoup(html.replace('\n',''), "html.parser")
for p in soup.find_all('div', attrs={'class': 'page_body'}):
tempArry.append(p.text)
tempStr="".join(tempArry)
paperArry.append(tempStr)
for d in soup.find_all('div',attrs={'class':'page_head text-center'}):
data=d.find('p').text
dataArry.append(data)
title = soup.find('title').text
title = title.replace('-浙大宁波理工学院', '')
titleArry.append(title)
'''
已经实现了正文内容的列表放置,接下去就是输出流对内容的输出
因为不会写二维列表o(╥﹏╥)o所以只得并将之保存为3个Excel文件
再最后Crtlc+v
'''
# ————————>通过清洗获取到了所有的标题、日期、正文内容,并置于3个列表中,下方将逐一输出列表内容
output=open('正文.xls','w',encoding='utf-8')
output.write('正文\n')
for i in range(len(paperArry)):
output.write(str(paperArry[i]))
output.write('\n')
output.close()
output=open('标题.xls','w',encoding='utf-8')
output.write('标题\n')
for i in range(len(titleArry)):
output.write(str(titleArry[i]))
output.write('\n')
output.close()
output=open('日期.xls','w',encoding='utf-8')
output.write('日期\n')
for i in range(len(dataArry)):
output.write(str(dataArry[i]))
output.write('\n')
output.close()
# ————————>已经在pyproject下产生了3个Excel文档目标完成