與Java類比,Java的網頁解析有Jsoup工具,Python的網頁解析工具對應的是BeautifulSoup。詳情可以閱讀其官方文檔。
這裏以爬取我的CSDN博客信息,包括獲取每篇博客的標題、鏈接、書寫日期、訪問量、評論數量等信息爲例,結合BeautifulSoup,進行網頁的解析,詳細的說明在代碼的註解中講解。博客首頁長這樣
這裏講解一個小技巧,在找爬取目標時,比如這裏要獲取博客總頁數爲,在網頁(如下)區域,直接“右鍵 --> 檢查”便可直接定位到這個區域對應的源碼中的位置,然後通過BeautifulSoup查找對應的元素,即可得到想要的信息。
代碼如下:
# coding=utf-8
# 對CSDN博客信息進行爬取,獲取博客的主題、鏈接、日期、訪問量、評論數等信息
import re
from urllib import request
from bs4 import BeautifulSoup
class CSDNSpider:
# 初始化爬取的頁號、鏈接以及封裝Header
def __init__(self, pageIndex=1, url="http://blog.csdn.net/u012050154/article/list/1"):
self.pageIndex = pageIndex
self.url = url
self.header = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"
}
# 請求網頁得到BeautifulSoup對象
def getBeautifulSoup(self, url):
# 請求網頁
req = request.Request(url, headers=self.header)
res = request.urlopen(req)
# 以html5lib格式的解析器解析得到BeautifulSoup對象
# 還有其他的格式如:html.parser/lxml/lxml-xml/xml/html5lib
soup = BeautifulSoup(res, 'html5lib')
return soup
# 獲取博客的博文分頁總數
def getTotalPages(self):
soup = self.getBeautifulSoup(self.url)
# 得到如下內容“209條 共14頁”
pageNumText = soup.find('div', 'pagelist').span.get_text()
# 利用正則表達式進一步提取得到分頁數
pageNum =re.findall(re.compile(pattern=r'共(.*?)頁'), pageNumText)[0]
return int(pageNum)
# 讀取每個頁面上各博文的主題、鏈接、日期、訪問量、評論數等信息
def getBlogInfo(self, pageIndx):
res = []
# 每頁的鏈接如http://blog.csdn.net/u012050154/article/list/1
# 所以按pageIndex更新url
url = self.url[0:self.url.rfind('/')+1] + str(pageIndx)
# 按url解析得到BeautifulSoup對象
soup = self.getBeautifulSoup(url)
# 得到目標信息
blog_items = soup.find_all('div', 'list_item article_item')
for item in blog_items:
# 博文主題
title = item.find('span', 'link_title').a.get_text()
blog = '標題:' + title
# 博文鏈接
link = item.find('span', 'link_title').a.get('href')
blog += '\t博客鏈接:' + link
# 博文發表日期
postdate = item.find('span', 'link_postdate').get_text()
blog += '\t發表日期:' + postdate
# 博文的訪問量
views_text = item.find('span', 'link_view').get_text() # 閱讀(38)
views = re.findall(re.compile(r'(\d+)'), views_text)[0]
blog += '\t訪問量:' + views
# 博文的評論數
comments_text = item.find('span', 'link_comments').get_text()
comments = re.findall(re.compile(r'(\d+)'), comments_text)[0]
blog += '\t評論數:' + comments + '\n'
print(blog)
res.append(blog)
return res
def saveFile(datas ,pageIndex):
path = "D:\\Program\\PythonCrawler\\CSDN\Data\\page_" + str(pageIndex + 1) + ".txt"
with open(path, 'w', encoding='gbk') as file:
file.write('當前頁:' + str(pageIndex + 1) + '\n')
for data in datas:
file.write(data)
if __name__=="__main__":
spider = CSDNSpider()
pageNum = spider.getTotalPages()
print("博客總頁數:", pageNum)
for index in range(pageNum):
print("正在處理第%s頁…" % (index+1))
blogsInfo = spider.getBlogInfo(index+1)
saveFile(blogsInfo, index)
結果:
參考文獻:
2、http://blog.csdn.net/fly_yr/article/details/51557656