爬蟲入門之爬取全唐詩并寫入數(shù)據(jù)庫

學習爬蟲有一段時間了资厉,今天想在此寫一篇基于新手對爬蟲入門的理解和初級爬蟲的構(gòu)建的文章厅缺。說白了,這篇文章,是寫給比我還菜的人看的湘捎。別看了诀豁,說的就是你。

一個簡單的爬蟲構(gòu)建我們采取一個簡單的思路:

抓取網(wǎng)頁

本次我們要抓取的頁面是全唐詩窥妇,它的首頁長這樣:


全唐詩首頁

依次點進去查看前幾個頁面的url舷胜,我們就會發(fā)現(xiàn)這些頁面之間的規(guī)律:


李世民頁

李治頁

末尾頁

好了,經(jīng)過簡單的觀察活翩,我們發(fā)現(xiàn)這些頁面的url有一個字段是從0001增長到了0900烹骨,一共九百頁,而其他地方則沒有變化纱新,這就好辦了展氓!但是也不要認為這個爬蟲就這么簡單,這些頁面要抓取就是一整頁脸爱,如何把這一整頁詩詞抽離出每首詩并寫入數(shù)據(jù)庫呢遇汞?接下來開始寫爬蟲

def gethtml(self,url):
        try :
            response = requests.get(url, headers=self.headers)
            response.encoding = 'gb18030'
        except :
            pass
        else :
            html = lxml.html.fromstring(response.text)
        finally:
            return html

這個方法是專門用來抓取網(wǎng)頁源代碼的,它接受一個網(wǎng)頁URL作為參數(shù)簿废,將網(wǎng)頁源碼轉(zhuǎn)換為html元素并返回空入,并且隨時準備被再次調(diào)用,至于response的編碼族檬,這里采取了gb18030歪赢,因為古詩詞里面的生僻字太多了,另外再說一句单料,爬蟲新手最頭疼的問題編碼可能算一個埋凯,采用requests庫的時候,我們一般調(diào)用網(wǎng)頁自身的編碼方式來給網(wǎng)頁的響應(yīng)流編碼:

response.encoding = response.apparent_encoding

但本教程是個例外扫尖,因為古詩詞里面的生僻字實在是太多了~~~

抽取元素

抽取元素我們使用xpath白对,高效又簡潔,正則表達式和beautifulsoup我都嘗試過换怖,但始終不如xpath深入我心甩恼。
檢查網(wǎng)頁源代碼,我們只要獲取DIV標簽下面的文本就好了


檢查元素
page = html.xpath('.//div/text()')

數(shù)據(jù)處理

上面我說過沉颂,這一頁詩拿下來我們需要對其做數(shù)據(jù)抽取条摸,這個時候不著急寫代碼,應(yīng)該停下來認真觀察拿到的詩文铸屉,選擇一個最好的規(guī)則應(yīng)用到其中钉蒲,做到最優(yōu)化的從詩文集合里分離單首詩文。這里我們注意到彻坛,每首詩的標題以「」包圍的子巾,我們的規(guī)則是上一個包含「」的行到下一個包含「」的行之間的內(nèi)容為一首詩帆赢,然后再把「」里的詩名跟后面的作者都抽離出來,最終寫入數(shù)據(jù)庫线梗,代碼如下:

import csv
import pymysql
conn = pymysql.connect(host='localhost',port=3306,user='root',password='xxxx',db='xxx',charset='utf8')
cur = conn.cursor()
with open('tangshi.txt','r+',encoding='utf8') as f:
    with open('tangshi.csv','w+',encoding='utf8') as csvfile:
        writer = csv.writer(csvfile)
        items = f.readlines()
        lst = []
        for index, item in enumerate(items):
            if '」' in item:
                lst.append(index)   #存放了所有標題的索引
        for index, item in enumerate(lst):  #以索引-值 的形式遍歷列表
            lst2 = items[item].split('「')
            author = lst2[-1].split('」')[-1]
            title = lst2[-1].split('」')[-2]
            if items[lst[index]] != items[lst[-1]]:    #如果這個標題不是最后一個
                context = items[lst[index]+1:lst[index+1]]
                context = ''.join([i.strip() for i in content if i ])       #做列表轉(zhuǎn)字符串的處理
            else:
                context = items[lst[index]+1:]    #否則詩文是該標題到此文本的末尾
                context = ''.join([i.strip() for i in context if i])
            sql = 'insert into tangshi(title,author,context) values(%s,%s,%s)'
            cur.execute(sql, (title.strip(),author.strip(),context.strip()))
            conn.commit()
cur.close()
conn.close()

說到最后,我把爬蟲的源代碼貼在這里怠益,python環(huán)境3.5仪搔,應(yīng)該可以直接運行。時間倉促加上語言不夠精煉蜻牢,可能有些地方說的不夠明白烤咧,請大家見諒,也歡迎讀者提出疑問或者獻上你寶貴的意見抢呆。下回見煮嫌!

import requests
import lxml.html

class myspider():
    #定義內(nèi)置方法,跟隨類一起創(chuàng)建抱虐,全局變量一般在此方法下聲明
    def __init__(self):
        user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 \
                    (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36'
        self.headers = {'User-Agent':user_agent}
        
    #定義獲取相應(yīng)url的html
    def gethtml(self,url):
        try :
            response = requests.get(url, headers=self.headers)
            response.encoding = 'gb18030'
        except :
            pass
        else :
            html = lxml.html.fromstring(response.text)
        finally:
            return html
    
    def getpage(self,url,num):
        with open('D:/{0}.txt'.format(num[1]),'w',encoding='utf8') as f : 
            for i in range(1,num[0]):
                print('正寫入第{0}頁'.format(i))
                s = str(i).zfill(4)
                print(s)
                ur =  url.format(s)
                html = self.gethtml(ur)
                print(ur)
                page = html.xpath('.//div/text()')
                for j in page :
                    if j : 
                        j.strip('\n')
                        f.write(j)
            print('寫入完畢')

if __name__=='__main__':
    sp = myspider()
    url1 = 'http://www.shigeku.org/shiku/gs/tangshi/qts_{0}.htm'
    d ={url1:[901,'tangshi']}
    for url,num in d.items():
        sp.getpage(url,num)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末昌阿,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子恳邀,更是在濱河造成了極大的恐慌懦冰,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谣沸,死亡現(xiàn)場離奇詭異刷钢,居然都是意外死亡,警方通過查閱死者的電腦和手機乳附,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門内地,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赋除,你說我怎么就攤上這事阱缓。” “怎么了贤重?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵茬祷,是天一觀的道長。 經(jīng)常有香客問我并蝗,道長祭犯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任滚停,我火速辦了婚禮沃粗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘键畴。我一直安慰自己最盅,他們只是感情好突雪,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著涡贱,像睡著了一般咏删。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上问词,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天督函,我揣著相機與錄音,去河邊找鬼激挪。 笑死辰狡,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的垄分。 我是一名探鬼主播宛篇,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼薄湿!你這毒婦竟也來了叫倍?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤嘿般,失蹤者是張志新(化名)和其女友劉穎段标,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體炉奴,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡逼庞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了瞻赶。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赛糟。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖砸逊,靈堂內(nèi)的尸體忽然破棺而出璧南,到底是詐尸還是另有隱情,我是刑警寧澤师逸,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布司倚,位于F島的核電站,受9級特大地震影響篓像,放射性物質(zhì)發(fā)生泄漏动知。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一员辩、第九天 我趴在偏房一處隱蔽的房頂上張望盒粮。 院中可真熱鬧,春花似錦奠滑、人聲如沸丹皱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽摊崭。三九已至讼油,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間呢簸,已是汗流浹背汁讼。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留阔墩,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓瓶珊,卻偏偏與公主長得像啸箫,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子伞芹,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容