[python爬蟲] Selenium爬取內容並存儲至MySQL數據庫

分類:IT技術 時間:2017-03-13

        前面我通過一篇文章講述了如何爬取CSDN的博客摘要等信息。通常,在使用Selenium爬蟲爬取數據後,需要存儲在TXT文本中,但是這是很難進行數據處理和數據分析的。這篇文章主要講述通過Selenium爬取我的個人博客信息,然後存儲在數據庫mysql中,以便對數據進行分析,比如分析哪個時間段發表的博客多、結合WordCloud分析文章的主題、文章閱讀量排名等。
        這是一篇基礎性的文章,希望對您有所幫助,如果文章中出現錯誤或不足之處,還請海涵。下一篇文章會簡單講解數據分析的過程。


一. 爬取的結果

        爬取的地址為:http://blog.csdn.net/Eastmount

        

        爬取並存儲至MySQL數據庫的結果如下所示:



        運行過程如下圖所示:




二. 完整代碼分析

        完整代碼如下所示:

# 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
    
#打開Firefox瀏覽器 設定等待加載時間    
driver = webdriver.Firefox()
wait = ui.WebDriverWait(driver,10)    

#獲取每個博主的博客頁面低端總頁碼     
def getPage():
    print 'getPage'
    number = 0      
    texts = driver.find_element_by_xpath("//div[@id='papelist']").text      
    print '頁碼', texts      
    m = re.findall(r'(\w*[0-9]+)\w*',texts) #正則表達式尋找數字      
    print '頁數:' + str(m[1])      
    return int(m[1])   
    
#主函數    
def main():
    #獲取txt文件總行數
    count = len(open("Blog_URL.txt",'rU').readlines())
    print count
    n = 0
    urlfile = open("Blog_URL.txt",'r')

    #循環獲取每個博主的文章摘信息 
    while n < count:  #這裏爬取2個人博客信息,正常情況count個博主信息
        url = urlfile.readline()
        url = url.strip("\n")
        print url
        driver.get(url)
        #獲取總頁碼
        allPage = getPage()
        print u'頁碼總數為:', allPage
        time.sleep(2)

        #數據庫操作結合
        try:
            conn=MySQLdb.connect(host='localhost',user='root',
                                 passwd='123456',port=3306, db='test01')
            cur=conn.cursor() #數據庫遊標

            #報錯:UnicodeEncodeError: 'latin-1' codec can't encode character
            conn.set_character_set('utf8')
            cur.execute('SET NAMES utf8;')
            cur.execute('SET CHARACTER SET utf8;')
            cur.execute('SET character_set_connection=utf8;')
            
            #具體內容處理
            m = 1 #第1頁
            while m <= allPage:
                ur = url + "/article/list/" + str(m)
                print ur
                driver.get(ur)
                
                #標題
                article_title = driver.find_elements_by_xpath("//div[@class='article_title']")
                for title in article_title:
                    #print url
                    con = title.text
                    con = con.strip("\n")
                    #print con + '\n'
                
                #摘要
                article_description = driver.find_elements_by_xpath("//div[@class='article_description']")
                for description in article_description:
                    con = description.text
                    con = con.strip("\n")
                    #print con + '\n'

                #信息
                article_manage = driver.find_elements_by_xpath("//div[@class='article_manage']")
                for manage in article_manage:
                    con = manage.text
                    con = con.strip("\n")
                    #print con + '\n'

                num = 0
                print u'長度', len(article_title)
                while num < len(article_title):
                    #插入數據 8個值
                    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].text
                    Description = article_description[num].text
                    Manage = article_manage[num].text
                    print Artitle
                    print Description
                    print Manage
                    #獲取作者
                    Author = url.split('/')[-1]
                    #獲取閱讀數和評論數
                    mode = re.compile(r'\d+\.?\d*')
                    YDNum = mode.findall(Manage)[-2]
                    PLNum = mode.findall(Manage)[-1]
                    print YDNum
                    print PLNum
                    #獲取發布時間
                    end = Manage.find(u' 閱讀')
                    FBTime = Manage[:end]
                    cur.execute(sql, (url, Author, Artitle, Description, Manage,FBTime,YDNum,PLNum))  
                  
                    num = num + 1
                else:
                    print u'數據庫插入成功'                
                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 + 1
                
    else:
        urlfile.close()
        print 'Load Over'
           
main()    


        在Blog_Url.txt文件中放置需要爬取用戶的博客地址URL,如下圖所示。註意在此處,作者預先寫了個爬取CSDN所有專家的URL代碼,這裏為訪問其他人用於提升閱讀量已省略。


        分析過程如下所示。
        1.獲取博主總頁碼
        首先從Blog_Url.txt讀取博主地址,然後訪問並獲取頁碼總數。代碼如下:
#獲取每個博主的博客頁面低端總頁碼     
def getPage():
    print 'getPage'
    number = 0      
    texts = driver.find_element_by_xpath("//div[@id='papelist']").text      
    print '頁碼', texts      
    m = re.findall(r'(\w*[0-9]+)\w*',texts) #正則表達式尋找數字      
    print '頁數:' + str(m[1])      
    return int(m[1])   
  
        比如獲取總頁碼位17頁,如下圖所示:



        2.翻頁DOM樹分析
        這裏的博客翻頁采用的是URL連接,比較方便。
        如:
http://blog.csdn.net/Eastmount/article/list/2
        故只需要 :1.獲取總頁碼;2.爬取每頁信息;3.URL設置進行循環翻頁;4.再爬取。
        也可以采用點擊"下頁"跳轉,沒有"下頁"停止跳轉,爬蟲結束,接著爬取下一個博主。


        3.獲取詳細信息:標題、摘要、時間
        然後審查元素分析每個博客頁面,如果采用BeautifulSoup爬取會報錯"Forbidden"。
        發現每篇文章都是由一個<div></div>組成,如下所示,只需要定位到該位置即可。



        這裏定位到該位置即可爬取,這裏需要分別定位標題、摘要、時間。


        代碼如下所示。註意,在while中同時獲取三個值,它們是對應的。

#標題
article_title = driver.find_elements_by_xpath("//div[@class='article_title']")
for title in article_title:
    con = title.text
    con = con.strip("\n")
    print con + '\n'
                
#摘要
article_description = driver.find_elements_by_xpath("//div[@class='article_description']")
for description in article_description:
    con = description.text
    con = con.strip("\n")
    print con + '\n'

#信息
article_manage = driver.find_elements_by_xpath("//div[@class='article_manage']")
for manage in article_manage:
    con = manage.text
    con = con.strip("\n")
    print con + '\n'

num = 0
print u'長度', len(article_title)
while num < len(article_title):
    Artitle = article_title[num].text
    Description = article_description[num].text
    Manage = article_manage[num].text
    print Artitle, Description, Manage

        4.特殊字符串處理
        獲取URL最後一個/後的博主名稱、獲取字符串時間、閱讀數代碼如下:

#獲取博主姓名
url = "http://blog.csdn.net/Eastmount"
print url.split('/')[-1]
#輸出: Eastmount

#獲取數字
name = "2015-09-08 18:06 閱讀(909) 評論(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


#獲取時間
end = name.find(r' 閱讀')
print name[:end]
#輸出: 2015-09-08 18:06

import 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)



三. 數據庫相關操作

        SQL語句創建表代碼如下:

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 '標題',
  `Description` varchar(400) COLLATE utf8_bin DEFAULT NULL COMMENT '摘要',
  `Manage` varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '信息',
  `FBTime` datetime DEFAULT NULL COMMENT '發布日期',
  `YDNum` int(11) DEFAULT NULL COMMENT '閱讀數',
  `PLNum` int(11) DEFAULT NULL COMMENT '評論數',
  `DZNum` int(11) DEFAULT NULL COMMENT '點贊數',
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=9371 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
        顯示如下圖所示:



        其中,python調用MySQL推薦下面這篇文字。
        [python] 專題九.Mysql數據庫編程基礎知識
        核心代碼如下所示:

# coding:utf-8 
import MySQLdb
 
try:
    conn=MySQLdb.connect(host='localhost',user='root',passwd='123456',port=3306, db='test01')
    cur=conn.cursor()
    
    #插入數據
    sql = '''insert into student values(%s, %s, %s)'''
    cur.execute(sql, ('yxz','111111', '10'))

    #查看數據
    print u'\n插入數據:'
    cur.execute('select * from student')
    for data in cur.fetchall():
        print '%s %s %s' % data
    cur.close()
    conn.commit()
    conn.close()
except MySQLdb.Error,e:
     print "Mysql Error %d: %s" % (e.args[0], e.args[1])


        最後希望文章對你有所幫助,如果文章中存在錯誤或不足之處,還請海涵~
        提高效率,提升科研,認真教學,娜美人生。
      (By:Eastmount 2017-03-13 下午1點半   http://blog.csdn.net/eastmount/ 





Tags: 瀏覽器 文章閱讀 Firefox python number

文章來源:


ads
ads

相關文章
ads

相關文章

ad