[python爬虫] Selenium爬取内容并存储至MySQL数据库
? ? ? ? 前面我通過(guò)一篇文章講述了如何爬取CSDN的博客摘要等信息。通常,在使用Selenium爬蟲(chóng)爬取數(shù)據(jù)后,需要存儲(chǔ)在TXT文本中,但是這是很難進(jìn)行數(shù)據(jù)處理和數(shù)據(jù)分析的。這篇文章主要講述通過(guò)Selenium爬取我的個(gè)人博客信息,然后存儲(chǔ)在數(shù)據(jù)庫(kù)MySQL中,以便對(duì)數(shù)據(jù)進(jìn)行分析,比如分析哪個(gè)時(shí)間段發(fā)表的博客多、結(jié)合WordCloud分析文章的主題、文章閱讀量排名等。
? ? ? ? 這是一篇基礎(chǔ)性的文章,希望對(duì)您有所幫助,如果文章中出現(xiàn)錯(cuò)誤或不足之處,還請(qǐng)海涵。下一篇文章會(huì)簡(jiǎn)單講解數(shù)據(jù)分析的過(guò)程。
一. 爬取的結(jié)果
? ? ? ? 爬取的地址為:http://blog.csdn.net/Eastmount
? ? ? ? 爬取并存儲(chǔ)至MySQL數(shù)據(jù)庫(kù)的結(jié)果如下所示:
? ? ? ? 運(yùn)行過(guò)程如下圖所示:
二. 完整代碼分析
? ? ? ? 完整代碼如下所示:
# coding=utf-8 from selenium import webdriver from selenium.webdriver.common.keys import Keys import selenium.webdriver.support.ui as ui import re import time import os import codecs import MySQLdb#打開(kāi)Firefox瀏覽器 設(shè)定等待加載時(shí)間 driver = webdriver.Firefox() wait = ui.WebDriverWait(driver,10) #獲取每個(gè)博主的博客頁(yè)面低端總頁(yè)碼 def getPage():print 'getPage'number = 0 texts = driver.find_element_by_xpath("//div[@id='papelist']").text print '頁(yè)碼', texts m = re.findall(r'(\w*[0-9]+)\w*',texts) #正則表達(dá)式尋找數(shù)字 print '頁(yè)數(shù):' + str(m[1]) return int(m[1]) #主函數(shù) def main():#獲取txt文件總行數(shù)count = len(open("Blog_URL.txt",'rU').readlines())print countn = 0urlfile = open("Blog_URL.txt",'r')#循環(huán)獲取每個(gè)博主的文章摘信息 while n < count: #這里爬取2個(gè)人博客信息,正常情況count個(gè)博主信息url = urlfile.readline()url = url.strip("\n")print urldriver.get(url)#獲取總頁(yè)碼allPage = getPage()print u'頁(yè)碼總數(shù)為:', allPagetime.sleep(2)#數(shù)據(jù)庫(kù)操作結(jié)合try:conn=MySQLdb.connect(host='localhost',user='root',passwd='123456',port=3306, db='test01')cur=conn.cursor() #數(shù)據(jù)庫(kù)游標(biāo)#報(bào)錯(cuò):UnicodeEncodeError: 'latin-1' codec can't encode characterconn.set_character_set('utf8')cur.execute('SET NAMES utf8;')cur.execute('SET CHARACTER SET utf8;')cur.execute('SET character_set_connection=utf8;')#具體內(nèi)容處理m = 1 #第1頁(yè)while m <= allPage:ur = url + "/article/list/" + str(m)print urdriver.get(ur)#標(biāo)題article_title = driver.find_elements_by_xpath("//div[@class='article_title']")for title in article_title:#print urlcon = title.textcon = con.strip("\n")#print con + '\n'#摘要article_description = driver.find_elements_by_xpath("//div[@class='article_description']")for description in article_description:con = description.textcon = con.strip("\n")#print con + '\n'#信息article_manage = driver.find_elements_by_xpath("//div[@class='article_manage']")for manage in article_manage:con = manage.textcon = con.strip("\n")#print con + '\n'num = 0print u'長(zhǎng)度', len(article_title)while num < len(article_title):#插入數(shù)據(jù) 8個(gè)值sql = '''insert into csdn_blog(URL,Author,Artitle,Description,Manage,FBTime,YDNum,PLNum)values(%s, %s, %s, %s, %s, %s, %s, %s)'''Artitle = article_title[num].textDescription = article_description[num].textManage = article_manage[num].textprint Artitleprint Descriptionprint Manage#獲取作者Author = url.split('/')[-1]#獲取閱讀數(shù)和評(píng)論數(shù)mode = re.compile(r'\d+\.?\d*')YDNum = mode.findall(Manage)[-2]PLNum = mode.findall(Manage)[-1]print YDNumprint PLNum#獲取發(fā)布時(shí)間end = Manage.find(u' 閱讀')FBTime = Manage[:end]cur.execute(sql, (url, Author, Artitle, Description, Manage,FBTime,YDNum,PLNum)) num = num + 1else:print u'數(shù)據(jù)庫(kù)插入成功' m = m + 1#異常處理except MySQLdb.Error,e:print "Mysql Error %d: %s" % (e.args[0], e.args[1])finally:cur.close() conn.commit() conn.close()n = n + 1else:urlfile.close()print 'Load Over'main()
? ? ? ? 在Blog_Url.txt文件中放置需要爬取用戶的博客地址URL,如下圖所示。注意在此處,作者預(yù)先寫(xiě)了個(gè)爬取CSDN所有專家的URL代碼,這里為訪問(wèn)其他人用于提升閱讀量已省略。
? ? ? ? 分析過(guò)程如下所示。
? ? ? ? 1.獲取博主總頁(yè)碼
? ? ? ? 首先從Blog_Url.txt讀取博主地址,然后訪問(wèn)并獲取頁(yè)碼總數(shù)。代碼如下:
#獲取每個(gè)博主的博客頁(yè)面低端總頁(yè)碼 def getPage():print 'getPage'number = 0 texts = driver.find_element_by_xpath("//div[@id='papelist']").text print '頁(yè)碼', texts m = re.findall(r'(\w*[0-9]+)\w*',texts) #正則表達(dá)式尋找數(shù)字 print '頁(yè)數(shù):' + str(m[1]) return int(m[1]) ? ? ? ? 比如獲取總頁(yè)碼位17頁(yè),如下圖所示:
? ? ? ? 2.翻頁(yè)DOM樹(shù)分析
? ? ? ? 這里的 博客翻頁(yè)采用的是URL連接,比較方便。
? ? ? ? 如: http://blog.csdn.net/Eastmount/article/list/2
? ? ? ? 故只需要 :1.獲取總頁(yè)碼;2.爬取每頁(yè)信息;3.URL設(shè)置進(jìn)行循環(huán)翻頁(yè);4.再爬取。
? ? ? ? 也可以采用點(diǎn)擊"下頁(yè)"跳轉(zhuǎn),沒(méi)有"下頁(yè)"停止跳轉(zhuǎn),爬蟲(chóng)結(jié)束,接著爬取下一個(gè)博主。
? ? ? ? 3.獲取詳細(xì)信息:標(biāo)題、摘要、時(shí)間
? ? ? ? 然后審查元素分析每個(gè)博客頁(yè)面,如果采用BeautifulSoup爬取會(huì)報(bào)錯(cuò)"Forbidden"。
? ? ? ? 發(fā)現(xiàn)每篇文章都是由一個(gè)<div></div>組成,如下所示,只需要定位到該位置即可。
? ? ? ? 這里定位到該位置即可爬取,這里需要分別定位標(biāo)題、摘要、時(shí)間。
? ? ? ? 代碼如下所示。注意,在while中同時(shí)獲取三個(gè)值,它們是對(duì)應(yīng)的。
? ? ? ? 4.特殊字符串處理
? ? ? ? 獲取URL最后一個(gè)/后的博主名稱、獲取字符串時(shí)間、閱讀數(shù)代碼如下:
#獲取博主姓名 url = "http://blog.csdn.net/Eastmount" print url.split('/')[-1] #輸出: Eastmount#獲取數(shù)字 name = "2015-09-08 18:06 閱讀(909) 評(píng)論(0)" print name import re mode = re.compile(r'\d+\.?\d*') print mode.findall(name) #輸出: ['2015', '09', '08', '18', '06', '909', '0'] print mode.findall(name)[-2] #輸出: 909#獲取時(shí)間 end = name.find(r' 閱讀') print name[:end] #輸出: 2015-09-08 18:06import time, datetime a = time.strptime(name[:end],'%Y-%m-%d %H:%M') print a #輸出: time.struct_time(tm_year=2015, tm_mon=9, tm_mday=8, tm_hour=18, tm_min=6, # tm_sec=0, tm_wday=1, tm_yday=251, tm_isdst=-1)
三. 數(shù)據(jù)庫(kù)相關(guān)操作
? ? ? ? SQL語(yǔ)句創(chuàng)建表代碼如下:
CREATE TABLE `csdn` (`ID` int(11) NOT NULL AUTO_INCREMENT,`URL` varchar(100) COLLATE utf8_bin DEFAULT NULL,`Author` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '作者',`Artitle` varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '標(biāo)題',`Description` varchar(400) COLLATE utf8_bin DEFAULT NULL COMMENT '摘要',`Manage` varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '信息',`FBTime` datetime DEFAULT NULL COMMENT '發(fā)布日期',`YDNum` int(11) DEFAULT NULL COMMENT '閱讀數(shù)',`PLNum` int(11) DEFAULT NULL COMMENT '評(píng)論數(shù)',`DZNum` int(11) DEFAULT NULL COMMENT '點(diǎn)贊數(shù)',PRIMARY KEY (`ID`) ) ENGINE=InnoDB AUTO_INCREMENT=9371 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ? ? ? ? 顯示如下圖所示:
? ? ? ? 其中,Python調(diào)用MySQL推薦下面這篇文字。
? ? ? ??[python] 專題九.Mysql數(shù)據(jù)庫(kù)編程基礎(chǔ)知識(shí)
? ? ? ? 核心代碼如下所示:
? ? ? ? 注意,在下載過(guò)程中,有的網(wǎng)站是新版本的,無(wú)法獲取頁(yè)碼。
? ? ? ? 比如:http://blog.csdn.net/michaelzhou224
? ? ? ? 這時(shí)需要簡(jiǎn)單設(shè)置,跳過(guò)這些鏈接,并保存到文件中,核心代碼如下所示:
#獲取每個(gè)博主的博客頁(yè)面低端總頁(yè)碼 def getPage():print 'getPage'number = 0 #texts = driver.find_element_by_xpath("//div[@id='papelist']").texttexts = driver.find_element_by_xpath("//div[@class='pagelist']").textprint 'testsss'print u'頁(yè)碼', textsif texts=="":print u'頁(yè)碼為0 網(wǎng)站錯(cuò)誤'return 0m = re.findall(r'(\w*[0-9]+)\w*',texts) #正則表達(dá)式尋找數(shù)字 print u'頁(yè)數(shù):' + str(m[1]) return int(m[1]) ? ? ? ? 主函數(shù)修改:
error = codecs.open("Blog_Error.txt", 'a', 'utf-8')#循環(huán)獲取每個(gè)博主的文章摘信息 while n < count: #這里爬取2個(gè)人博客信息,正常情況count個(gè)博主信息url = urlfile.readline()url = url.strip("\n")print urldriver.get(url+"/article/list/1")#print driver.page_source#獲取總頁(yè)碼allPage = getPage()print u'頁(yè)碼總數(shù)為:', allPage#返回錯(cuò)誤,否則程序總截住if allPage==0:error.write(url + "\r\n")print u'錯(cuò)誤URL'continue; #跳過(guò)進(jìn)入下一個(gè)博主time.sleep(2)#數(shù)據(jù)庫(kù)操作結(jié)合try:.....
? ? ? ? 最后希望文章對(duì)你有所幫助,如果文章中存在錯(cuò)誤或不足之處,還請(qǐng)海涵~
? ? ? ? 提高效率,提升科研,認(rèn)真教學(xué),娜美人生。
? ? ? (By:Eastmount 2017-03-13 下午1點(diǎn)半? ? http://blog.csdn.net/eastmount/ ) ?
總結(jié)
以上是生活随笔為你收集整理的[python爬虫] Selenium爬取内容并存储至MySQL数据库的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: [数据库] Navicat for My
- 下一篇: [数据库] Navicat for My