一、内容:
写一个爬虫,对某个博友的博客的每个文章列表进行爬取,并提取标题、链接、时间、阅读量、评论数等信息写入本地txt文档中。以一页面创建一个txt文档。
爬取页面截图:
爬取内容截图
二、原理:
1.使用BeautifulSoup的python库,BeautifulSoup的好处是可以减少正则表达式的使用,更简洁简单,节省编写正则表达式的时间,容错性也更强。
2.另再使用html5lib解析器,能以浏览器方式解析文档,生成html5格式的文档。
对博文进行一页一页进行抓取,需获取得总的页数:
# 求总页数 def get_page(self): req = urllib.request.Request(url=self.url, headers=self.headers) res = urllib.request.urlopen(req) # 从csdn博客主页抓取的内容是压缩后的内容,先解压缩 data = res.read() data = ungzip(data) # 用"utf-8"格式编码 data = data.decode('utf-8') # 获取BeautifulSoup对象 s = BeautifulSoup(data, "html5lib") page_tag = s.find("div","pagelist") pagesData = page_tag.span.get_text() # 获取总页的正则 pagesNum = re.findall(re.compile(pattern=r'共(.*?)页'), pagesData)[0] return pagesNum
对每页面的每个博文列表信息进行抓取:
# 读取博文信息 def read_data(self): # ret 元组用来存放博文信息的集合 ret = [] req = urllib.request.Request(url=self.url, headers=self.headers) res = urllib.request.urlopen(req) # 获取博文的信息 data = res.read() # 从csdn博客主页抓取的内容是压缩后的内容,先解压缩 data = ungzip(data) data = data.decode('utf-8') #print(data) # 创建BeautifuSoup 对象 s = BeautifulSoup(data, "html5lib") # 通过find_all 获取全部 博文一整段的信息 items = s.find_all('div', "list_item article_item") for item in items: # 标题 title = item.find('span', "link_title").a.get_text() # 链接 link = item.find('span', "link_title").a.get("href") # 写作时间 write_time = item.find('span', "link_postdate").get_text() # 阅读量 re.compile(r'(.∗?)')正则获取的数据为 “阅读(223)”所以223为[3] reader_nums = re.findall(re.compile(r'(.∗?)'), item.find('span', "link_view").get_text())[3] # 评论量 re.compile(r'(.∗?)')正则获取的数据为 “评论(2)”所以2为[3] comments = re.findall(re.compile(r'(.∗?)'), item.find('span', "link_comments").get_text())[3] ret.append('日期:' + write_time + '\r\n'+'标题:' + title + '\r\n'+'链接:http://blog.csdn.net' + link + '\r\n' + '阅读:' + reader_nums + '\t评论:' + comments + '\r\n') return ret写一个保存信息到本地文件:
# 定义保存文件的函数 整个页面的博客信息加入 def save_File(data, i): path = "D:\\py_project\\\\"+str(i+1)+".txt" file = open(path, 'wb') # 先把页page写进去文件 page = '当前页:'+str(i+1)+'\r\n' file.write(page.encode('gbk')) # 再将博文的日期和访问量等信息写进文件 d代表一个博客信息 for d in data: print(d) d = str(d)+'\r\n' # 加一个隔一行 file.write(d.encode('gbk')) file.close() 三、完整代码:
# csdn 博客爬虫 # 日期 主题 链接 访问量 评论个数 import urllib.request import re import gzip from bs4 import BeautifulSoup # 定义保存文件的函数 整个页面的博客信息加入 def save_File(data, i): path = "D:\\py_project\\\\"+str(i+1)+".txt" file = open(path, 'wb') # 先把页page写进去文件 page = '当前页:'+str(i+1)+'\r\n' file.write(page.encode('gbk')) # 再将博文的日期和访问量等信息写进文件 d代表一个博客信息 for d in data: print(d) d = str(d)+'\r\n' # 加一个隔一行 file.write(d.encode('gbk')) file.close() # 解压缩数据 def ungzip(data): try: data = gzip.decompress(data) except: print("未压缩,无需解压") return data # 爬虫类 class CSNDSpider: # 初始化 def __init__(self, pageIdx=1, url="http://blog.csdn.net/fly_yr/article/list/1"): self.pageIdx = pageIdx self.url = url self.headers = { "Connection": "keep-alive", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 " "(KHTML, like Gecko) Chrome/51.0.2704.63 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "zh-CN,zh;q=0.8", "Host": "blog.csdn.net" } # 求总页数 def get_page(self): req = urllib.request.Request(url=self.url, headers=self.headers) res = urllib.request.urlopen(req) # 从csdn博客主页抓取的内容是压缩后的内容,先解压缩 data = res.read() data = ungzip(data) # 用"utf-8"格式编码 data = data.decode('utf-8') # 获取BeautifulSoup对象 s = BeautifulSoup(data, "html5lib") page_tag = s.find("div","pagelist") pagesData = page_tag.span.get_text() # 获取总页的正则 pagesNum = re.findall(re.compile(pattern=r'共(.*?)页'), pagesData)[0] return pagesNum # 设置要抓取的页面 def setPage(self, idx): self.url = self.url[0:self.url.rfind('/')+1]+str(idx) # 读取博文信息 def read_data(self): # ret 元组用来存放博文信息的集合 ret = [] req = urllib.request.Request(url=self.url, headers=self.headers) res = urllib.request.urlopen(req) # 获取博文的信息 data = res.read() # 从csdn博客主页抓取的内容是压缩后的内容,先解压缩 data = ungzip(data) data = data.decode('utf-8') #print(data) # 创建BeautifuSoup 对象 s = BeautifulSoup(data, "html5lib") # 通过find_all 获取全部 博文一整段的信息 items = s.find_all('div', "list_item article_item") for item in items: # 标题 title = item.find('span', "link_title").a.get_text() # 链接 link = item.find('span', "link_title").a.get("href") # 写作时间 write_time = item.find('span', "link_postdate").get_text() # 阅读量 re.compile(r'(.∗?)')正则获取的数据为 “阅读(223)”所以223为[3] reader_nums = re.findall(re.compile(r'(.∗?)'), item.find('span', "link_view").get_text())[3] # 评论量 re.compile(r'(.∗?)')正则获取的数据为 “评论(2)”所以2为[3] comments = re.findall(re.compile(r'(.∗?)'), item.find('span', "link_comments").get_text())[3] ret.append('日期:' + write_time + '\r\n'+'标题:' + title + '\r\n'+'链接:http://blog.csdn.net' + link + '\r\n' + '阅读:' + reader_nums + '\t评论:' + comments + '\r\n') return ret if __name__ == '__main__': # 定义爬虫对象 cs = CSNDSpider() # 获取页面总数 pagesNum = int(cs.get_page()) print("博文总页数:",pagesNum) # 循环将每页获取的博文存入本地 for idx in range(pagesNum): # 设置页 cs.setPage(idx) print("当前页:", idx+1) # 获取信息 page_data = cs.read_data() # 将信息存入本地 save_File(page_data, idx)
四、运行结果: