Python 爬簡(jiǎn)書首頁(yè)插入Mongo數(shù)據(jù)庫(kù)

之前的文章是爬蟲(chóng)糗事百科并插入到MySQL數(shù)據(jù)庫(kù),使用的是BeautifulSoup解析靜態(tài)網(wǎng)頁(yè),select(返回列表)、find_all(返回列表)和find(返回單個(gè)結(jié)果)以及正則定位獲取網(wǎng)頁(yè)數(shù)據(jù),pymysql鏈接插入本地MySQL數(shù)據(jù)庫(kù)。為了擴(kuò)展自己的爬蟲(chóng)技能,今天的代碼是爬蟲(chóng)異步加載的簡(jiǎn)書首頁(yè)文章,使用的是lxml解析網(wǎng)頁(yè),XPath定位獲取網(wǎng)頁(yè)數(shù)據(jù),以及pymongo鏈接插入本地Mongo數(shù)據(jù)庫(kù)(之前不懂MongoDB,看到很多人都使用Mongo數(shù)據(jù)庫(kù)存儲(chǔ)爬蟲(chóng)數(shù)據(jù),特別學(xué)習(xí)了一下,感覺(jué)這個(gè)非關(guān)系型數(shù)據(jù)庫(kù)還是很好用的)。爬取的首頁(yè)文章數(shù)據(jù)包括:標(biāo)題,作者,發(fā)表時(shí)間,閱讀量,評(píng)論數(shù),點(diǎn)贊數(shù),打賞數(shù),所投專題,代碼的完成參考了loading_miracle的文章,他的文章思路清晰,圖文并茂,很適合學(xué)習(xí)!下面是程序代碼,每一句都加了注釋說(shuō)明,方便整理思路,代碼的寫法存在許多不規(guī)范的地方,還請(qǐng)大家留言指教,謝謝。

import requests
from lxml import etree
#import re
import pymongo
#構(gòu)建爬取簡(jiǎn)書首頁(yè)的類
class JianshuSpider(object):
    #鏈接Mongo數(shù)據(jù)庫(kù)
    client = pymongo.MongoClient('localhost', 27017)
    #創(chuàng)建數(shù)據(jù)庫(kù) mydb (應(yīng)該叫連接數(shù)據(jù)庫(kù),比較創(chuàng)建數(shù)據(jù)庫(kù)更合適)
    mydb = client['mydb']
    #創(chuàng)建數(shù)據(jù)表 jianshu
    jianshu = mydb['jianshu']
    #請(qǐng)求頭
    headers = {
      'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
    }
    #創(chuàng)建一個(gè)數(shù)組,用以存儲(chǔ)文章的id,作為異步加載的請(qǐng)求參數(shù)
    params = []
    #Class的構(gòu)造函數(shù)(我習(xí)慣這么稱呼它)
    def __init__(self):
        pass
    #獲取異步加載的url的函數(shù)(15頁(yè)),并請(qǐng)求數(shù)據(jù)
    def totalpage(self):
        for i in range(0,15):
            data = '&'.join(self.params)
            url = 'http://www.itdecent.cn/?' + data + '&page={}'.format(i)
            self.get_data(url)
    #爬取數(shù)據(jù),并插入Mongo數(shù)據(jù)庫(kù)的函數(shù)
    def get_data(self,url):
        #模擬瀏覽器訪問(wèn)網(wǎng)頁(yè)
        html = requests.get(url,self.headers).text
        #etree.HTML解析網(wǎng)頁(yè)內(nèi)容返回給respone
        response = etree.HTML(html)
        #獲取請(qǐng)求文章的ID并存入數(shù)組并作為請(qǐng)求攜帶參數(shù)
        ids = response.xpath('//*[@id="list-container"]/ul/li')
        for one in ids:
            one = 'seen_snote_ids[]=' + one.xpath('@data-note-id')[0]
            self.params.append(one)
        #xpath得到所有包含目標(biāo)內(nèi)容的div的集合
        div_list = response.xpath('//*[@id="list-container"]/ul/li/div')
        #for循環(huán)分別讀取d集合中的目標(biāo)數(shù)據(jù)
        for div in div_list:
            #定位獲取文章標(biāo)題數(shù)據(jù)-->text()
            title = div.xpath('a/text()')[0]
            #定位獲取作者名字?jǐn)?shù)據(jù)-->text()
            author = div.xpath('div[1]/div/a/text()')[0]
            #定位獲取發(fā)表時(shí)間數(shù)據(jù)-->非文本text()而是屬性@
            release_time = div.xpath('div[1]/div/span/@data-shared-at')[0]
            #定位獲取文章閱讀量(用XPath無(wú)法定位獲取數(shù)據(jù))
            #reading_num = div.xpath('div[2]/a[2]/text()')[0]
            #定位獲取文章評(píng)論數(shù)(用XPath無(wú)法定位獲取數(shù)據(jù))
            #comment_num = div.xpath('div[2]/a[3]/text()')
            #定位獲取點(diǎn)贊數(shù)量
            like_num = div.xpath('div[2]/span/text()')[0]
            #打賞數(shù)和所投專題可能為None,顧需特別處理
            #判斷所投專題
            flg1 = div.xpath('div[2]/a[1]/text()')[0]
            topic = div.xpath('div[2]/a[1]/text()')[0] if flg1!=None else ""
            #判斷打賞數(shù)
            flg2 = div.xpath('div[2]/span[2]/text()')
            play_num = div.xpath('div[2]/span[2]/text()')[0] if len(flg2)>0 else 0
            #爬取數(shù)據(jù)后,構(gòu)建數(shù)據(jù)字典
            data = {
                '標(biāo)題':title,
                '作者':author,
                '發(fā)布時(shí)間':release_time,
                #'閱讀數(shù)':reading_num,
                #'評(píng)論數(shù)':comment_num,
                '點(diǎn)贊數(shù)':like_num,
                '所投專題':topic,
                '打賞數(shù)':play_num
            }
            #向數(shù)據(jù)庫(kù)插入數(shù)據(jù)
            self.jianshu.insert_one(data)
if __name__ == '__main__':
    #初始化簡(jiǎn)書爬蟲(chóng)這個(gè)類
    jssy_spider = JianshuSpider()
    #調(diào)用簡(jiǎn)書爬蟲(chóng)類的totalpage()函數(shù)
    jssy_spider.totalpage()

插入MongDB效果:

簡(jiǎn)書mongo.png

除文章的閱讀數(shù)和評(píng)論數(shù)沒(méi)有爬到,其他都插入到Mongo數(shù)據(jù)庫(kù)中了,很奇怪不知道為什么用XPath無(wú)法定位獲取這兩類數(shù)據(jù),嘗試參照loading_miracle的文章改用正則表達(dá)式獲取,但是發(fā)現(xiàn)自己使用正則獲取數(shù)據(jù)后,分頁(yè)異步加載的數(shù)據(jù)不正確。第一次使用XPath,很多定位技巧都不掌握,還請(qǐng)大神幫忙解決用XPath定位這兩類數(shù)據(jù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容