一个可识别翻页的简易Python爬虫程序
同学拿出一个需求:从某课程教学网站上爬取所有课程的主页面,以及课程简介栏目内容。
于是在之前做的那个练手级的Python爬虫程序中进行修改,最终实现了该功能。与之前那个爬虫不同,这里每一个大类的课程下面都有上千个具体课程名,分为几百页,所以需要识别翻页的问题。
另外,由于网站结构不同,这里的程序整体实现思路也稍有不同,大致如下:
1、从该网站首页获取所有课程大类的链接放到list中
2、遍历上述list,对于每一个链接,对应的都是具体课程名的列表,24个为一页。
2.1 获取该页面中包含的具体课程地址链接,并读取出具体内容,将相关信息保存到本地txt文件中;
2.2 是否有‘下一页’链接。如果有,将此‘下一页’的链接设置为当前页,交给循环进行迭代;如果没有,说明该大类已经读取完毕,继续外层循环
2.3 外层循环结束
具体代码:
from urllib.request import urlopen from bs4 import BeautifulSoup import time #所需变量初始化及准备工作 #记录程序开始时间 start = time.clock() #设置网站首页地址 rooturl=‘http://www.jingpinke.com/‘ #创建一个list用于保存课程大类的链接地址 indexlist=[] ##====================以下为方法========================## ‘‘‘ 方法名:getContent 作用:从pagelist中的url中解析出相关内容,并保存到本地文本中 参数:含有具体课程内容的网址 ‘‘‘ def getContent(url): try: currentPage=urlopen(url).read() #读取源码 except Exception as err: print(‘联网超时,退出当前页面。‘) currentText=BeautifulSoup(currentPage) #利用bs进行解析 #获取课程标题、时间、教师等信息,并将它们以空格连接起来作为文件名使用 title=currentText.find(‘div‘,{‘class‘:‘cTitle‘}).find(‘h2‘).get_text() teacher=currentText.find(‘div‘,{‘class‘:‘course_final_ohter‘}).findAll(‘span‘)[0].get_text() university=currentText.find(‘div‘,{‘class‘:‘course_final_ohter‘}).findAll(‘span‘)[1].get_text() date=currentText.find(‘div‘,{‘class‘:‘course_final_ohter‘}).findAll(‘span‘)[2].get_text() rank=currentText.find(‘div‘,{‘class‘:‘course_final_ohter‘}).findAll(‘span‘)[3].get_text() classtitle=date+‘ ‘+university+‘ ‘+rank+‘ ‘+title+‘ ‘+teacher #获取课程简介内容 briefintro=currentText.find(‘pre‘).get_text() #以标题为文件名,创建txt文件,并写入正文内容 f=open(‘file/‘+classtitle+‘.txt‘,‘w+‘, encoding=‘utf-8‘) f.write(classtitle+‘\r\n‘+briefintro) print(classtitle+‘.txt‘) f.close() #开始爬取 # 1、先解析根目录,获取13个目标链接 print(‘解析根目录‘) rawtext=urlopen(rooturl).read() soup = BeautifulSoup(rawtext) targetDiv=soup.find(‘div‘,{‘class‘:‘benke_fenlei‘}) catalogLinks=targetDiv.findAll(‘a‘) for l in catalogLinks: indexlist.append(l.get(‘href‘)) print(‘根目录解析完成‘) #2、从indexlist中逐个读取地址,获取该课程大类下的每个课程的地址 for index in indexlist: currentpage=index #初始时,将某大类的链接设为当前页 count=1 # 计数器,计算某大类下的课程数目 while True: print("当前页:"+currentpage) try: rawtext=urlopen(currentpage).read() #读取当前页 except Exception as err: print(‘联网超时,退出当前大类。‘) break soup= BeautifulSoup(rawtext) #解析当前页 eachclass=soup.find(‘div‘,{‘class‘:‘course_list‘}).findAll(‘table‘) #获取课程名列表,每一个课程名都放在一个table中 for c in eachclass: #循环获取每一个课程的链接地址 print(str(count)+‘:http://course.jingpinke.com‘+c.find(‘a‘).get(‘href‘)) #打印该地址 count=count+1 # 计数器自增 getContent(‘http://course.jingpinke.com‘+c.find(‘a‘).get(‘href‘)) #调用getContent方法,获取该页内容,并保存 if soup.find(id=‘nextPage‘)==None: # 如果当前页未发现下一页链接 说明该大类已经获取完毕 print(‘没有了。‘) # 打印结束 break #退出外层循环,继续下一大类 else: #否则,说明还有下一页 nextpageurl=‘http://course.jingpinke.com/search‘+soup.find(id=‘nextPage‘).find(‘a‘).get(‘href‘) # 获取当前页中的下一页链接 currentpage=nextpageurl #将当前页中的下一页链接设为当前页 print(‘下一页:‘+nextpageurl) # 打印下一步要处理的地址 #4、计算程序执行过程耗时 end = time.clock() print (end-start)
说明:
由于我是在sublime text2环境下写的程序,之前将该软件默认的字符编码设为gbk,这导致写入的文件名中含有非中文字符(比如阿拉伯文)时,出现gbk不能编译的错误,后来在csdn论坛上看到,如果在操作系统的环境变量中加入PYTHONIOENCODING项,项值为utf-8,其含义是将Python的默认IO编码设置为utf-8,然后将sublime text2中的pyton.sublim-build中人为添加的endoding:gbk删掉,重启sublime
text2后,即可解决上述问题。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。