Python3爬取百科詞條+導(dǎo)入MySQL數(shù)據(jù)庫

本文主要介紹使用Python爬蟲爬取Python百度詞條的信息 主要參考慕課網(wǎng)的《開發(fā)簡(jiǎn)單爬蟲》以及一些數(shù)據(jù)庫操作

開發(fā)工具

---工欲善其事 必先利其器

首先 這里開發(fā)工具用的Python3.6+Pycharm+MySQL5.7+SQLyog
前面2個(gè)的安裝直接網(wǎng)上搜下教程一大堆 而且免去了配置環(huán)境變量的操作,MySQL數(shù)據(jù)庫(安裝教程也一大堆)現(xiàn)在最新版是5.7 它的安裝與之前的有點(diǎn)不同


圖片發(fā)自簡(jiǎn)書App

注意到?jīng)] 安裝時(shí)多了一個(gè)必須選項(xiàng) 安裝InnoDB時(shí)設(shè)置password 然后再填入即可 其它步驟和一般軟件沒什么區(qū)別
然后去搜索引擎下載SQLyog工具(用Pycharm自帶的dataBase應(yīng)該也可以 有興趣的小伙伴可以去試試 ) 連接數(shù)據(jù)庫


圖片發(fā)自簡(jiǎn)書App

點(diǎn)擊連接 出錯(cuò)的可以看看 進(jìn)入控制面板→管理工具→服務(wù)→看MySQL service是否打開 連接好后創(chuàng)建數(shù)據(jù)庫baikeurl 然后建url表

再建立4個(gè)欄位 分別是 id urlname urlhref urlcontent
圖片發(fā)自簡(jiǎn)書App

爬蟲的架構(gòu)及具體流程

1.傳入目標(biāo)url后調(diào)用URL管理器
2.URL管理器對(duì)URL進(jìn)行具體的判斷與檢索后傳入網(wǎng)頁下載器
3.網(wǎng)頁下載器工作后將網(wǎng)頁傳入網(wǎng)頁解析器
4.將解析后的內(nèi)容(url拓瞪,title,content等)傳入輸出器
5.最后輸出器進(jìn)行數(shù)據(jù)操作(寫入文件 導(dǎo)入數(shù)據(jù)庫等)
整個(gè)過程采用了嚴(yán)格的面向?qū)ο笏枷?每一過程具體的函數(shù)都封裝在相應(yīng)文件中


圖片發(fā)自簡(jiǎn)書App
圖片發(fā)自簡(jiǎn)書App

實(shí)例分析

要爬取的鏈接:http://baike.baidu.com/item/Python
通過瀏覽器的開發(fā)者工具分析可知 百度百科的詞條
鏈接:/item/……的形式
標(biāo)題: <dd class="lemmaWgt-lemmaTitle-title"><h1>……</h1> 內(nèi)容:<div class="lemma-summary">……</div>

廢話不多說 直接上代碼 關(guān)鍵地方帶注釋 一個(gè)包括5個(gè)文件

爬蟲調(diào)度端(主頁)

spider.py文件

import html_downloader
import html_outputer
import html_parser
import url_manager

#爬蟲主函數(shù)
class SpiderMain(object):
    def __init__(self):
        self.urls = url_manager.UrlManager()
        self.downloader = html_downloader.HtmlDownloader()
        self.parser = html_parser.HtmlParser()
        self.outputer = html_outputer.HtmlOutputer()
#抓取過程函數(shù)
    def craw(self, root_url):
        count = 1
        self.urls.add_new_url(root_url)
        while self.urls.has_new_url():
            try:
                new_url = self.urls.get_new_url()
                print('craw %d : %s' % (count, new_url))
                html_cont = self.downloader.download(new_url)
                new_urls, new_data = self.parser.parse(new_url, html_cont)
                self.urls.add_new_urls(new_urls)
                self.outputer.collect_data(new_data)
                if count == 1000:
                    break
                count = count+1
            except:
                print('craw failed')

        self.outputer.into_mysql()
if __name__ == '__main__':
    rooturl = 'http://baike.baidu.com/item/Python'
    obj_spider = SpiderMain()
    obj_spider.craw(rooturl)

url管理器
url_manager.py文件

# -*- coding: utf-8 -*-
class UrlManager(object):
    def __init__(self):
        self.new_urls = set()
        self.old_urls = set()
    def add_new_url(self, root_url):
        if root_url is None:
            return
        if root_url not in self.new_urls and root_url not in self.old_urls:
            self.new_urls.add(root_url)
    def has_new_url(self):
        return len(self.new_urls) != 0
    def get_new_url(self):
        new_url = self.new_urls.pop()
        self.old_urls.add(new_url)
        return new_url
    def add_new_urls(self, new_urls):
        if new_urls is None or len(new_urls) == 0:
            return
        for url in new_urls:
            self.add_new_url(url)

網(wǎng)頁下載器
html_downloader.py文件

import urllib.request
class HtmlDownloader(object):
    def download(self, new_url):
        if new_url is None:
            return None
        response =  urllib.request.urlopen(new_url)
        if response.getcode() != 200:
            return None
        return response.read()

網(wǎng)頁解析器
html_parse.py文件

import re
import urllib
from urllib import parse

from bs4 import BeautifulSoup

class HtmlParser(object):
    def parse(self, new_url, html_cont):
        if new_url is None or html_cont is None:
            return
        soup = BeautifulSoup(html_cont,'html.parser'    )
        new_urls = self._get_new_urls(new_url,soup)
        new_data = self._get_new_data(new_url,soup)
        return new_urls,new_data

    def _get_new_urls(self, new_url, soup):
        new_urls = set()
#獲取要爬取的鏈接
        links = soup.find_all('a',href=re.compile(r'/item/\w+'))
        for link in links:
            new_url1 = link['href']
            new_full_url = parse.urljoin(new_url, new_url1)
            new_urls.add(new_full_url)
        return new_urls
    def _get_new_data(self, new_url, soup):
        res_data = {}
        res_data['url'] = new_url
#<dd class="lemmaWgt-lemmaTitle-title"><h1>Python</h1>
#獲取詞條的標(biāo)題
        title_node = soup.find('dd',class_='lemmaWgt-lemmaTitle-title').find('h1')
        res_data['title'] = title_node.get_text()
#獲取詞條的內(nèi)容
        summary_node = soup.find('div',class_='lemma-summary')
        res_data['summary'] = summary_node.get_text()
        return res_data

輸出器

html_outputer.py文件

class HtmlOutputer(object):
    def __init__(self):
        self.datas = []
    def collect_data(self, new_data):
        if new_data is None:
            return
        print(new_data['summary'])
        self.datas.append(new_data)
#數(shù)據(jù)庫操作函數(shù)
    def into_mysql(self):
        i = 0
        for data in self.datas:
            conn = pymysql.Connect(
                host='127.0.0.1',
                user='你的用戶名',
                password='你的密碼',
                db='數(shù)據(jù)庫名稱',
                port=3306,
                charset='utf8mb4'
            )
            try:
                cursor = conn.cursor()
                i += 1
                sql = 'insert into `urls`(`id`,`urlname`,`urlhref`,`urlcontent`)values(%s,%s,%s,%s)'
#執(zhí)行上面的sql語句 并傳入4個(gè)參數(shù)
#分別是id,title叠纷,url噩凹,content
                cursor.execute(sql, (i, data['title'],data['url'],data['summary']))
                conn.commit()
            finally:

                conn.close()

注:關(guān)于編碼問題 因?yàn)樵摼W(wǎng)頁就是采用的utf-8編碼 所以無需調(diào)用encode()方法編碼 直接data['summary']的內(nèi)容就是正常顯示 若將數(shù)據(jù)寫入文件 則需要第二個(gè)參數(shù)傳入encoding='' 指定文件編碼方式 測(cè)試時(shí)盡量不用Windows系統(tǒng)自帶的IE瀏覽器 由于默認(rèn)編碼問題 會(huì)導(dǎo)致顯示亂碼(當(dāng)時(shí)就是被這個(gè)問題困擾) 換用記事本或其它瀏覽器就正常顯示了
最后點(diǎn)擊運(yùn)行

圖片發(fā)自簡(jiǎn)書App

運(yùn)行 爬取網(wǎng)頁正常 然后我們?nèi)タ纯磾?shù)據(jù)庫
圖片發(fā)自簡(jiǎn)書App

數(shù)據(jù)庫也導(dǎo)入成功了 到此 我們的需求就完成了 最后附上github地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末儒飒,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子诅迷,更是在濱河造成了極大的恐慌,老刑警劉巖众旗,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件罢杉,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡贡歧,警方通過查閱死者的電腦和手機(jī)滩租,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來利朵,“玉大人律想,你說我怎么就攤上這事∩艿埽” “怎么了技即?”我有些...
    開封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)樟遣。 經(jīng)常有香客問我而叼,道長(zhǎng),這世上最難降的妖魔是什么豹悬? 我笑而不...
    開封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任葵陵,我火速辦了婚禮,結(jié)果婚禮上屿衅,老公的妹妹穿的比我還像新娘埃难。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開白布涡尘。 她就那樣靜靜地躺著忍弛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪考抄。 梳的紋絲不亂的頭發(fā)上细疚,一...
    開封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音川梅,去河邊找鬼疯兼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛贫途,可吹牛的內(nèi)容都是我干的吧彪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼丢早,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼姨裸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起怨酝,我...
    開封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤傀缩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后农猬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體赡艰,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年斤葱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了慷垮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡揍堕,死狀恐怖换帜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鹤啡,我是刑警寧澤惯驼,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站递瑰,受9級(jí)特大地震影響祟牲,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜抖部,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一说贝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧慎颗,春花似錦乡恕、人聲如沸言询。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽运杭。三九已至,卻和暖如春函卒,著一層夾襖步出監(jiān)牢的瞬間辆憔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來泰國打工报嵌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留虱咧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓锚国,卻偏偏與公主長(zhǎng)得像腕巡,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子血筑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

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