Python3 爬虫(八) -- BeautifulSoup之再次爬取CSDN博文

在Python3爬虫(五)博文使用utllib基本函数以及正则表达式技术实现了爬取csdn全部博文信息的任务。
上一篇,我们学习了BeautifulSoup这样一个优秀的Python库,必须有效利用起来。那么我们就利用BeautifulSoup4重新实现一次爬取csdn博文的任务。

由于我修改了博客配置,首页主题换了一下,我们基于新的主题查看网页,如下图所示:



同样的,确认要提取的信息,以及博文总页数。

分析网页源码

url以及请求报头的设置与之前相同,在这儿就不啰嗦了,主要详述怎样利用BeautifulSoup4获取我们的目标信息,先来看一下当前网页源码:
博文信息模块:

页码信息模块:


提取博文页数

[python]  view plain  copy
  1. #求总页数  
  2. def getPages(self):  
  3.     req = urllib.request.Request(url=self.url, headers=self.headers)  
  4.     page = urllib.request.urlopen(req)  
  5.   
  6.     # 从我的csdn博客主页抓取的内容是压缩后的内容,先解压缩  
  7.     data = page.read()  
  8.     data = ungzip(data)  
  9.     data = data.decode('utf-8')  
  10.   
  11.     # 得到BeautifulSoup对象  
  12.     soup = BeautifulSoup(data,'html5lib')  
  13.     # 计算我的博文总页数  
  14.     tag = soup.find('div',"pagelist")  
  15.     pagesData = tag.span.get_text()  
  16.     #输出392条  共20页,找到其中的数字  
  17.     pagesNum = re.findall(re.compile(pattern=r'共(.*?)页'),pagesData)[0]  
从上述代码可以看出,当我们读取网页数据之后,定义BeautifulSoup对象,调用find函数可读出“392条 共20页”,而我们要的是20这个数字,然后在利用正则表达式提取出来即可。

提取博文信息

[python]  view plain  copy
  1. #读取博文信息  
  2.     def readData(self):  
  3.         ret=[]  
  4.         req = urllib.request.Request(url=self.url, headers=self.headers)  
  5.         res = urllib.request.urlopen(req)  
  6.   
  7.         # 从我的csdn博客主页抓取的内容是压缩后的内容,先解压缩  
  8.         data = res.read()  
  9.         data = ungzip(data)  
  10.         data = data.decode('utf-8')  
  11.   
  12.         soup=BeautifulSoup(data,"html5lib")  
  13.         #找到所有的博文代码模块  
  14.         items = soup.find_all('div',"list_item article_item")  
  15.         for item in items:  
  16.             #标题、链接、日期、阅读次数、评论个数  
  17.             title = item.find('span',"link_title").a.get_text()  
  18.             link = item.find('span',"link_title").a.get('href')  
  19.             writeTime = item.find('span',"link_postdate").get_text()  
  20.             readers = re.findall(re.compile(r' (.?) '),item.find('span',"link_view").get_text())[0]  
  21.             comments = re.findall(re.compile(r' (.?) '),item.find('span',"link_comments").get_text())[0]  
  22.   
  23.             ret.append('日期:'+writeTime+'\n标题:'+title  
  24.                        +'\n链接:http://blog.csdn.net'+link  
  25.                        +'\n'+'阅读:'+readers+'\t评论:'+comments+'\n')  
  26.         return ret  
从代码可以看出,我们提取每个元素的信息可以很简便的采用BeautifulSoup的函数,不需要构造复杂的正则表达式,大大简化了操作。

完整代码

其它操作与之前相同,就不赘述了,下面给出完整代码:
[python]  view plain  copy
  1. ''''' 
  2. program: csdn博客爬虫2 
  3. function: 采用BeautifulSoup技术实现对我的csdn主页所有博文的日期、主题、访问量、评论个数信息爬取 
  4.  
  5. version: python 3.5.1 
  6. time: 2016/06/01 
  7. autuor: yr 
  8. '''  
  9.   
  10.   
  11. import urllib.request,re,time,random,gzip  
  12. from bs4 import BeautifulSoup  
  13.   
  14. #定义保存文件函数  
  15. def saveFile(data,i):  
  16.     path = "E:\\projects\\Spider\\06_csdn2\\papers\\paper_"+str(i+1)+".txt"  
  17.     file = open(path,'wb')  
  18.     page = '当前页:'+str(i+1)+'\n'  
  19.     file.write(page.encode('gbk'))  
  20.     #将博文信息写入文件(以utf-8保存的文件声明为gbk)  
  21.     for d in data:  
  22.         d = str(d)+'\n'  
  23.         file.write(d.encode('gbk'))  
  24.     file.close()  
  25.   
  26. #解压缩数据  
  27. def ungzip(data):  
  28.     try:  
  29.         #print("正在解压缩...")  
  30.         data = gzip.decompress(data)  
  31.         #print("解压完毕...")  
  32.     except:  
  33.         print("未经压缩,无需解压...")  
  34.     return data  
  35.   
  36. #CSDN爬虫类  
  37. class CSDNSpider:  
  38.     def __init__(self,pageIdx=1,url="http://blog.csdn.net/fly_yr/article/list/1"):  
  39.         #默认当前页  
  40.         self.pageIdx = pageIdx  
  41.         self.url = url[0:url.rfind('/') + 1] + str(pageIdx)  
  42.         self.headers = {  
  43.             "Connection""keep-alive",  
  44.             "User-Agent""Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 "  
  45.                           "(KHTML, like Gecko) Chrome/51.0.2704.63 Safari/537.36",  
  46.             "Accept""text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",  
  47.             "Accept-Encoding""gzip, deflate, sdch",  
  48.             "Accept-Language""zh-CN,zh;q=0.8",  
  49.             "Host""blog.csdn.net"  
  50.         }  
  51.   
  52.     #求总页数  
  53.     def getPages(self):  
  54.         req = urllib.request.Request(url=self.url, headers=self.headers)  
  55.         page = urllib.request.urlopen(req)  
  56.   
  57.         # 从我的csdn博客主页抓取的内容是压缩后的内容,先解压缩  
  58.         data = page.read()  
  59.         data = ungzip(data)  
  60.         data = data.decode('utf-8')  
  61.   
  62.         # 得到BeautifulSoup对象  
  63.         soup = BeautifulSoup(data,'html5lib')  
  64.         # 计算我的博文总页数  
  65.         tag = soup.find('div',"pagelist")  
  66.         pagesData = tag.span.get_text()  
  67.         #输出392条  共20页,找到其中的数字  
  68.         pagesNum = re.findall(re.compile(pattern=r'共(.*?)页'),pagesData)[0]  
  69.         return pagesNum  
  70.   
  71.     #设置要抓取的博文页面  
  72.     def setPage(self,idx):  
  73.         self.url = self.url[0:self.url.rfind('/')+1]+str(idx)  
  74.   
  75.     #读取博文信息  
  76.     def readData(self):  
  77.         ret=[]  
  78.         req = urllib.request.Request(url=self.url, headers=self.headers)  
  79.         res = urllib.request.urlopen(req)  
  80.   
  81.         # 从我的csdn博客主页抓取的内容是压缩后的内容,先解压缩  
  82.         data = res.read()  
  83.         data = ungzip(data)  
  84.         data = data.decode('utf-8')  
  85.   
  86.         soup=BeautifulSoup(data,"html5lib")  
  87.         #找到所有的博文代码模块  
  88.         items = soup.find_all('div',"list_item article_item")  
  89.         for item in items:  
  90.             #标题、链接、日期、阅读次数、评论个数  
  91.             title = item.find('span',"link_title").a.get_text()  
  92.             link = item.find('span',"link_title").a.get('href')  
  93.             writeTime = item.find('span',"link_postdate").get_text()  
  94.             readers = re.findall(re.compile(r' (.?) '),item.find('span',"link_view").get_text())[0]  
  95.             comments = re.findall(re.compile(r' (.?) '),item.find('span',"link_comments").get_text())[0]  
  96.   
  97.             ret.append('日期:'+writeTime+'\n标题:'+title  
  98.                        +'\n链接:http://blog.csdn.net'+link  
  99.                        +'\n'+'阅读:'+readers+'\t评论:'+comments+'\n')  
  100.         return ret  
  101.   
  102. #定义爬虫对象  
  103. cs = CSDNSpider()  
  104. #求取  
  105. pagesNum = int(cs.getPages())  
  106. print("博文总页数: ",pagesNum)  
  107.   
  108. for idx in range(pagesNum):  
  109.     cs.setPage(idx)  
  110.     print("当前页:",idx+1)  
  111.     #读取当前页的所有博文,结果为list类型  
  112.     papers = cs.readData()  
  113.     saveFile(papers,idx)  

GitHub完整代码链接 --- 请戳我吧~~~


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值