pyspider爬蟲框架

  • 官方文檔:http://docs.pyspider.org/
  • PySpider:一個(gè)國人編寫的強(qiáng)大的網(wǎng)絡(luò)爬蟲系統(tǒng)并帶有強(qiáng)大的WebUI淘菩。采用Python語言編寫星虹,分布式架構(gòu)挣饥,支持多種數(shù)據(jù)庫后端自晰,強(qiáng)大的WebUI支持腳本編輯器剑逃,任務(wù)監(jiān)視器滞伟,項(xiàng)目管理器以及結(jié)果查看器
  • pyspider是作者之前做的一個(gè)爬蟲架構(gòu)的開源化實(shí)現(xiàn)。主要的功能需求是:
  1. 抓取炕贵、更新調(diào)度多站點(diǎn)的特定的頁面
  2. 需要對頁面進(jìn)行結(jié)構(gòu)化信息提取
  3. 靈活可擴(kuò)展,穩(wěn)定可監(jiān)控 而這也是絕大多數(shù)python爬蟲的需求 —— 定向抓取野崇,結(jié)構(gòu)化化解析称开。但是面對結(jié)構(gòu)迥異的各種網(wǎng)站,單一的抓取模式并不一定能滿足乓梨,靈活的抓取控制是必須的鳖轰。為了達(dá)到這個(gè)目的,單純的配置文件往往不夠靈活扶镀,于是蕴侣,通過腳本去控制抓取是我最后的選擇。 而去重調(diào)度臭觉,隊(duì)列昆雀,抓取,異常處理蝠筑,監(jiān)控等功能作為框架狞膘,提供給抓取腳本,并保證靈活性什乙。最后加上web的編輯調(diào)試環(huán)境挽封,以及web任務(wù)監(jiān)控,即成為了這套框架臣镣。
  • pyspider的設(shè)計(jì)基礎(chǔ)是:以python腳本驅(qū)動(dòng)的抓取環(huán)模型爬蟲
  1. 通過python腳本進(jìn)行結(jié)構(gòu)化信息的提取辅愿,follow鏈接調(diào)度抓取控制智亮,實(shí)現(xiàn)最大的靈活性
  2. 通過web化的腳本編寫、調(diào)試環(huán)境点待。web展現(xiàn)調(diào)度狀態(tài)
  3. 抓取環(huán)模型成熟穩(wěn)定阔蛉,模塊間相互獨(dú)立,通過消息隊(duì)列連接亦鳞,從單進(jìn)程到多機(jī)分布式靈活拓展

ubuntu安裝:

  • 添加依賴

sudo apt-get install python python-dev python-distribute python-pip libcurl4-openssl-dev libxml2-dev libxslt1-dev python-lxml libssl-dev zlib1g-dev

sudo apt-get install phantomjs

pip3 install pyspider

windows直接進(jìn)行pip安裝即可

運(yùn)行

pyspider all

打開瀏覽器馍忽,輸入:

http://127.0.0.1:5000

出現(xiàn)以下界面運(yùn)行成功

image.png

創(chuàng)建項(xiàng)目:點(diǎn)擊Create

image.png
  • 填寫項(xiàng)目名稱和起始url
  • Mode:Slime有些功能還沒有完善,選擇Script
  • 點(diǎn)擊創(chuàng)建

進(jìn)去之后就可以寫你的代碼了

左邊這一欄可以簡單運(yùn)行一下你的代碼燕差。

右邊是寫你的代碼的遭笋,下面該介紹一下相關(guān)的參數(shù)和方法了

# pyspider爬蟲的主類,我們在這里進(jìn)行爬取徒探,解析和儲存信息
class Handler(BaseHandler):
    # crawl_config:在這個(gè)參數(shù)中可以做全局的設(shè)置(UA瓦呼,Headers,proxy...)
    # itags:做一個(gè)標(biāo)記测暗,如果頁面或版本號發(fā)生變化央串,會再請求一次
    crawl_config = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0',
        # 'itags':'v1'
    }
    # 創(chuàng)建mongodb數(shù)據(jù)庫連接
    mongo_client = pymongo.MongoClient('127.0.0.1', 27017)
    # 創(chuàng)建或指定數(shù)據(jù)庫
    db = mongo_client['lianjia']
    # 獲取數(shù)據(jù)庫下的集合
    col = db['lianjiacol']

    # 創(chuàng)建mysql數(shù)據(jù)庫連接
     mysql_cli = pymysql.Connect(
        '127.0.0.1','root','密碼','數(shù)據(jù)庫名稱',3306,charset='utf8'
     )
    # 創(chuàng)建游標(biāo)
     cursor = mysql_cli.cursor()
  • self.crawl中的參數(shù)
    # 每隔一天進(jìn)行一次重復(fù)請求(重新執(zhí)行on_start方法)
    @every(minutes=24 * 60)
    def on_start(self):


         crawl:根據(jù)crawl發(fā)起請求,
         exetime:延時(shí)碗啄,
         data:默認(rèn)get請求质和,當(dāng)發(fā)起一個(gè)post請求用data={}傳遞參數(shù)
         忽略ssl證書,默認(rèn)不忽略:validate_cert=False
         fetch_type=‘js’,加載動(dòng)態(tài)頁面稚字,也可以執(zhí)行js代碼:
        js_script='''
                function() {
                  window.scrollTo(0,document.body.scrollHeight);
                  return 123;
             }
             '''
         save饲宿,對應(yīng)的是一個(gè)字典,傳遞參數(shù)
         附加到url傳遞參數(shù):parmars = {}
        """
       例: self.crawl('http://www.baidu.com' callback=self.index_page,save={'a':'b'},parmars={'name':'zhangsan'})
          def index_page(self,response):
                  print(response.url)  --> 'http://www.baidu.com/?name=zhangsan'
                  response.save['a'] --> b
        """
        self.crawl(url, callback=self.index_page, validate_cert=False)
  • xpath胆描、css
    # 同樣的url在十天之內(nèi)不會重復(fù)爬取
    @config(age=10 * 24 * 60 * 60)
    def index_page(self, response):

        # response.doc:pyquery對象
        # response.etree:返回lxml
        # 提取每一個(gè)房源的詳情url地址
        hourse_infos = response.doc(
            'ul.sellListContent li.clear.LOGCLICKDATA'
        )  # css
         hourse_infos = response.etree.xpath(
            'ul[@class="sellListContent"]/ li[@class="clear LOGCLICKDATA"]'
        ) # xpath

        for hourse in hourse_infos.items():
            detail_url = hourse(
                'div.title a'
            ).attr.href
            
         detail_url = hourse.xpath(
                'div[@class="title"]/a/@href'
            )
            self.crawl(detail_url, callback=self.detail_page, validate_cert=False)

        # 提取下一頁發(fā)起請求

        # 提取json方法:data = response.doc('.page-box.house-lst-page-box').attr.page-data
        data = response.etree.xpath('//div[@class="page-box house-lst-page-box"]/@page-data')[0]
        json_data = json.loads(data)
        print(json_data)
        cur_page = int(json_data['curPage'])
        total_page = int(json_data['totalPage'])
        if cur_page < total_page:
            # 發(fā)起下一頁
            next_page = cur_page + 1
            next_url = 'https://bj.lianjia.com/ershoufang/pg{}/'.format(str(next_page))
            self.crawl(next_url, callback=self.index_page, validate_cert=False)

    # for each in response.doc('a[href^="http"]').items():
    #    self.crawl(each.attr.href, callback=self.detail_page)

    @config(priority=2)
    def detail_page(self, response):
        print('二手房獲取成功')
        # 獲取二手房詳情信息
        info = {}
        # 標(biāo)題
        # info['title'] = response.doc('h1.main').attr.title
        info['title'] = response.doc('h1.main').text()
        # 其他信息
        info['subTitle'] = response.doc('div.sub').text()
        # 關(guān)注人數(shù)
        info['attrnNum'] = response.doc('#favCount').text()
        # 幾人看過
        info['lookNum'] = response.doc('#cartCount').text()
        # 總價(jià)
        info['price '] = response.doc('span.total').text()
        # 單價(jià)
        info['unitPriceValue'] = response.doc('span.unitPriceValue').text() + response.doc(
            'span.unitPriceValue i').text()
        # 大小
        info['size'] = response.doc('div.room div.mainInfo').text()
        # 幾層
        info['height'] = response.doc('div.room div.subInfo').text()
        # 方向
        info['diriction'] = response.doc('div.type div.mainInfo').text()
        # 類型
        info['type'] = response.doc('div.room div.subInfo').text()
        # print(info)
        return info

    def on_result(self, result):
        print('獲取到結(jié)果', result)
        if result:
            try:
                # mongo
                self.col.insert(result)
                # mysql
                 sql = """
                    INSERT INTO lianjia(%s) VALUES (%S)
                 """%(','.join(result.keys()),','.join(['%s']*len(result)))
                 data = list(result.values())
                 self.cursor.execute(sql,data)
                 self.mysql_cli.commit()
                print('數(shù)據(jù)存儲成功')
            
            except Exception as err:
                print('數(shù)據(jù)庫插入失敗', err)
                 self.mysql_cli.rollback()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瘫想,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子昌讲,更是在濱河造成了極大的恐慌国夜,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件短绸,死亡現(xiàn)場離奇詭異车吹,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)鸠按,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門礼搁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人目尖,你說我怎么就攤上這事馒吴。” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵饮戳,是天一觀的道長豪治。 經(jīng)常有香客問我,道長扯罐,這世上最難降的妖魔是什么负拟? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮歹河,結(jié)果婚禮上掩浙,老公的妹妹穿的比我還像新娘。我一直安慰自己秸歧,他們只是感情好厨姚,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著键菱,像睡著了一般谬墙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上经备,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天拭抬,我揣著相機(jī)與錄音,去河邊找鬼侵蒙。 笑死造虎,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的纷闺。 我是一名探鬼主播累奈,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼急但!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起搞乏,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤波桩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后请敦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體镐躲,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年侍筛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了萤皂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡匣椰,死狀恐怖裆熙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤入录,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布蛤奥,位于F島的核電站,受9級特大地震影響僚稿,放射性物質(zhì)發(fā)生泄漏凡桥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一蚀同、第九天 我趴在偏房一處隱蔽的房頂上張望缅刽。 院中可真熱鬧,春花似錦蠢络、人聲如沸衰猛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腕侄。三九已至,卻和暖如春芦疏,著一層夾襖步出監(jiān)牢的瞬間冕杠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工酸茴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留分预,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓薪捍,卻偏偏與公主長得像笼痹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子酪穿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

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