Python爬取笑話儲存在mysql裡

來源:互聯網
上載者:User

標籤:pymysql   pre   col   包含   連結   錯誤   iter   type   ams   

  首先確定要爬取的笑話網站,我是直接百度笑話搜到的第一個網站,網址是http://www.jokeji.cn/,點進去發現網頁構建在我看來還是比較複雜的,由於還是初學者,首先得先找到網頁資源集中所在,找出其中的規律,然後才好有針對性的爬取資源。對於這個網址,我發現在左邊側欄有一個笑話大全的分類框。這個看起來基本上包括了全站的文字笑話了。在這個分類框下有許多小的分類,點進小的分類後是此分類下的所有笑話網頁列表,每個網頁裡麵包含一些笑話,我們最終是要把這一個一個網頁裡的笑話爬取儲存起來。

  爬取思路:爬取http://www.jokeji.cn/,得到一個html頁面,分析此html頁面,獲得分類框裡的所有分類的url地址,遍曆每一個分類的url,爬取分類url的html網頁,分析分類url網頁,得到全部笑話網頁列表,遍曆笑話網頁列表url,得到最終的包含一個一個笑話的html頁面,擷取笑話,儲存到mysql資料庫。

  爬取我用的是Google瀏覽器,在這個網站下按F12就可以看到網頁原始碼了,此時要分析這個笑話大全的分類框的結構,以便使用pythonRegex擷取到我們想要的資訊。

  一般篩選內容都會選擇目標內容組件的上層容易唯一標識的組件,在這裡我選擇了<div class=”joketype l_left”></div>這個html,這個div可以包含所有分類的內容,然後再進行一次篩選就可以把所有url篩選出來了。到了分類子頁面我看了一下url的規律,這個分類的url都是/listXX_1.htm開始,發現分類頁面裡面有個尾頁的按鈕的url剛好是結束,並且url的.htm前面的那個數字遞增,所以就很好爬取所有笑話頁面了,至於提取笑話就不再多說了,直接上所有代碼。

  mysql資料庫儲存模組代碼,檔案名稱為mysql.py。

import pymysqldef insert(joke):    #擷取連結    conn=pymysql.connect(host=‘127.0.0.1‘,user=‘root‘,passwd=‘123456‘,db=‘python‘)    cur=conn.cursor()    #sql語句,%s是預留位置(%s是唯一的,不論什麼資料類型都使用%s)防止sql注入    sql=‘insert into joke(joke) VALUES(%s)‘    #params=(‘eric‘,‘wuhan‘) #參數 插入單條    #li=[(‘a1‘,‘b1‘),(‘a2‘,‘b2‘)] #批量插入參數    #reCount=cur.execute(sql,params)    reCount=cur.executemany(sql,joke) #批量插入    conn.commit() #提交,執行多條命令只需要commit一次就可以    cur.close()    conn.close()def get_one():    #擷取連結    conn=pymysql.connect(host=‘127.0.0.1‘,user=‘root‘,passwd=‘123456‘,db=‘python‘)    cur=conn.cursor()    sql1=‘select number from number‘    reCount=cur.execute(sql1)    number=cur.fetchone()[0]+1    sql2=‘select joke from joke where id=%s‘    reCount=cur.execute(sql2,number)    joke=cur.fetchone()[0]    sql3=‘update number set number=%s where number=%s‘    params=(number,number-1)    reCount=cur.execute(sql3,params)    conn.commit()    cur.close()    conn.close()

注意:pymysql模組是需要安裝的,一般現在python都預設有pip包管理,沒有這個模組直接在命令列執行:pip pymysql即可。需事先在mysql資料庫裡建立python資料庫,表joke,表有兩列,一列是id,我設定其為int類型的自增的主鍵屬性,一列joke,設定為text類型,存放笑話。insert函數是傳入一個joke的tuple型別參數,這個tuple裡面存放是一條一條字串,每條字串表示一個笑話,insert函數的功能是將這個tuple元組的笑話插入到資料庫。get_one函數是得到一條笑話,在這裡我添加一個表專門來儲存笑話取到哪了,以免讀取重複笑話,這個表名字是number,裡面有一個欄位,number,我實現插入了一條記錄,值為0。

  爬蟲代碼,檔案名稱為spider.py。

import urllibfrom urllib import requestimport reimport chardetimport mysqlimport time‘‘‘找到http://www.jokeji.cn/list29_1.htm笑話列表擷取第一個笑話網頁http://www.jokeji.cn/jokehtml/bxnn/2018080417455037.htm遍曆完所有笑話網頁擷取下一個笑話列表,重複遍曆,直至此分類笑話遍曆完遍曆下一個分類‘‘‘class Spider():    url=‘http://www.jokeji.cn/jokehtml/bxnn/2018073023294432.htm‘    header = {        ‘User-Agent‘:‘Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Mobile Safari/537.36‘,        ‘Accept-Encoding‘: ‘‘,      ‘Referer‘:‘http://www.jokeji.cn/list29_1.htm‘    }    classifys=[] #list集合,儲存笑話分類url    #擷取html文本    def __fetch_content(self):        cookie_html = request.Request(Spider.url,headers=Spider.header)        cookie_html = request.urlopen(cookie_html)        htmls=cookie_html.read()        #使用chardet擷取到htmls的編碼格式        encoding=chardet.detect(htmls)        encoding=encoding[‘encoding‘]        #不加ignore的時候總是出現字元轉換錯誤,說明有非法字元,必須加上ignore忽略非法字元        htmls=htmls.decode(encoding,‘ignore‘)        time.sleep(0.1)        return htmls        #擷取笑話分類url    def __analysis_classify(self):        Spider.url=‘http://www.jokeji.cn/‘        Spider.header[‘Referer‘]=‘http://www.jokeji.cn/‘        htmls=self.__fetch_content()        root_pattern=‘<div class="joketype l_left">([\s\S]*?)</div>‘        classify_pattern=‘<a href="([\s\S]*?)">‘        root_html=re.findall(root_pattern,htmls)        Spider.classifys=re.findall(classify_pattern,str(root_html))            #擷取當前頁面裡的所有笑話,返回一個tuple    def __analysis(self,htmls):        anchors=[]        root_pattern=‘<span id="text110">([\s\S]*?)</span>‘        juck_pattern=‘<P>\d、([\s\S]*?)</P>‘        root_html=re.findall(root_pattern,htmls)        for html in root_html:            jucks=re.findall(juck_pattern,html)            #替換分行符號            c=re.compile(‘<[b|B][r|R]\s*/*>‘)            for i in jucks:                i=c.sub(‘\n‘,i)                anchors.append(i)                #i=i.replace(‘<BR>‘,‘\n‘)            return anchors        return anchors    #爬取原創笑話    def __analysis_yuanchuangxiaohua(self,url):        url=‘http://www.jokeji.cn‘+url        pass            #爬取分類下的笑話    def __analysis_joke(self):        Spider.header[‘Referer‘]=‘http://www.jokeji.cn/‘        root_pattern=‘<div class="list_title">([\s\S]*?)</div>‘        page_pattern=‘<a href="([\s\S]*?)"\s*target="_blank"\s*>‘        for classify in Spider.classifys:            try:                if ‘/yuanchuangxiaohua‘ in classify:                    self.__analysis_yuanchuangxiaohua(classify)                classify=‘http://www.jokeji.cn‘+classify                Spider.url=classify                htmls=self.__fetch_content()                #記錄分類裡面最大頁面數                           max_number=int(re.findall(‘[\s\S]*?(\d*?)\.htm">尾頁</a>‘,htmls)[0])                #開始遍曆每一大頁,一大頁包含很多小頁面,小頁面裡面才是笑話            except BaseException:                continue            for bigpage_number in range(1,max_number+1):                try:                    bigpage_url=classify                    temp=re.compile(‘(\d*).htm‘)                    #更改url,因為分類下每一大頁都是有規律的,都是.htm前面的數字從1加到最大頁面數                    bigpage_url=temp.sub(str(bigpage_number)+‘.htm‘,bigpage_url)                    #替換url                    Spider.url=bigpage_url                    htmls=self.__fetch_content()                    root_html=re.findall(root_pattern,htmls)                    #擷取一大頁裡面的小頁面的url地址                    pages=re.findall(page_pattern,root_html[0])                    #遍曆所有小頁面url,擷取其中的笑話                except BaseException:                    continue                for page in pages:                    try:                        Spider.url=‘http://www.jokeji.cn‘+page                        htmls=self.__fetch_content()                        tuples=self.__analysis(htmls)                        #插入到資料庫                        mysql.insert(tuples)                    except BaseException:                        continue    def go(self):        self.__analysis_classify()        self.__analysis_joke()spider=Spider()spider.go()

由於笑話分類裡的原創笑話的頁面格式不同,所以就差這個還沒實現。初學,第一次寫部落格記錄,下載了編寫部落格的openLiveWriter發現很難用,還是用網頁寫好一點。

 

 

 

Python爬取笑話儲存在mysql裡

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.