这段时间发现越来越痴迷于Python,特别是Python3,所以一边看书,一边就想动手做点实践。由于实验室有收集新闻语料的需求,所以就想着以凤凰网新闻网址为目标,试着写一个爬虫如何? 结果还真实现了! 当然 只是入门级的哦,请各位看官多提意见。
工具:python3, Beautiful Soup4
基本思想:先给定一个目标url,它应该是一个索引类型页面(如http://news.ifeng.com/),然后以广度优先的思路 去分析这个url中包含的具体新闻页面链接和其它索引页面链接的页面。接着以迭代的思想,获取其下层索引页面中包含的所有新闻页面链接和索引页面链接,直至当前站下索引页面都处理完。最后提取具体新闻页面的内容
原理图:
具体代码:
说明:如果只考虑收集页面url而不考虑抓取其中的内容,那么可以无视getContent()方法。 由于本人希望能够抓取具体的新闻内容,而且只是实验该方法的可行性,所以选取了范围较小的凤凰国际新闻,根据凤凰新闻具体标签结构来识别其中的时间、标题、正文等。也就是说,如果要抓取其它网站内容的话,getContent()方法中的目标标签也要作相应的修改。本人尚未尝试。
from urllib.request import urlopen from bs4 import BeautifulSoup import time #所需变量初始化及准备工作 #记录程序开始时间 start = time.clock() #创建一个list用于保存要抽取的网站 rooturl=input(‘请输入起始目录网址:‘) #创建一个list用于保存索引型页面的url indexlist=[] #创建一个list用于保存具体内容页面的url pagelist=[] ##====================以下为方法========================## ‘‘‘ 方法名:parseHref 作用:从参数给定的url中解析出其中包含的索引类url和具体页面类url,并分别保存到不同的list中,同时确保值唯一 参数: url:要解析的网址 ‘‘‘ #获取解析结果 def parseHref(url): rawtext=urlopen(url).read() #抓取当前页面 soup = BeautifulSoup(rawtext) #使用bs模块获取其结构树 newslinks=soup.findAll("a") #从中找到所有链接标签 for a in newslinks: #循环处理所有a标签 currentLink=a.get(‘href‘) #获取当前标签的链接地址 if currentLink and currentLink.find(url)==0: # 如果不为空,则包含有当前要解析的网址,则说明网址初步合法,不会跳转到外部链接 if currentLink.find(‘detail_‘)>0: # 如果地址中含有detail_子串,说明这是一个具体页面 if currentLink in pagelist: #判断该页面在pagelist中是否存在 如果存在 print(‘ 地址已经存在,不处理‘) # 不处理 else: #如果不存在 pagelist.extend([currentLink]) #则新增进去 print(‘具体页面list新增:‘,currentLink) elif currentLink.endswith(‘/‘): 如果当前地址是以/结尾,说明这是一个索引页面,也就是说它下面还有下级页面 if currentLink in indexlist: # 判断该页面在indexlist中是否存在 如果存在 print(‘ 地址已经存在,不处理‘) #不处理 else: # 如果不存在, indexlist.extend([currentLink]) # 则新增进去 print(‘索引页面list新增:‘,currentLink) ‘‘‘ 方法名:getContent 作用:从pagelist中的url中解析出时间、标题、正文内容,并保存到本地文本中 参数:无参数 ‘‘‘ def getContent(): #解析当前Pagelist列表中保存的所有具体内容页面 print(‘解析具体页面‘) for p in pagelist: currentPage=urlopen(p).read() currentText=BeautifulSoup(currentPage) print(p) #获取新闻发布时间 newstime=currentText.find(‘span‘,{‘itemprop‘:‘datePublished‘}) if newstime: newstime=newstime.get_text().replace(‘年‘,‘-‘) newstime=newstime.replace(‘月‘,‘-‘) newstime=newstime.replace(‘日‘,‘‘) newstime=newstime.replace(‘:‘,‘:‘) #获取新闻标题 newstitle=currentText.find("h1") if len(newstitle)>0: #print(newstitle.get_text()) newstitle=newstitle.get_text().replace(‘\t‘,‘‘) newstitle=newstitle.replace(‘/‘,‘/‘) #获取新闻正文 newscontent= currentText.find(id="main_content" ) if newscontent: #以时间和标题为文件名,创建txt文件,并写入正文内容 f=open(‘file/‘+newstime+" "+newstitle+‘.txt‘,‘w+‘, encoding=‘utf-8‘) f.write(newscontent.get_text()) print(newstime+" "+newstitle+‘.txt‘) f.close() print(‘处理完成:‘,len(pagelist),‘个页面。‘) #开始爬取 # 1、先解析根目录 print(‘解析根目录‘) parseHref(rooturl) print(‘根目录解析完成‘) # 2、分析indexlist中的值迭代进行解析,直至所有索引页面都被分析过 print(‘解析获取的索引页面‘) for i in indexlist: parseHref(i) print(‘索引页面解析完成‘) #3、解析pagelist中所有具体页面 getContent() #4、计算程序执行过程耗时 end = time.clock() print (end-start)
结果截图: