雖然我是做Android的,但也會用python抓點數(shù)據(jù)用用

前言

最近也是在工作之余開發(fā)一個Android App,采用當前比較火的框架retrofit+rxjava+rxbus+lamda+greenDao+glide等媳谁。有興趣的小伙伴可以關注一下我的github開源項目。本文主要介紹的是如何利用python抓取糗百的熱門段子友酱。

開發(fā)環(huán)境

  1. Mac Os
  2. Python 2.7.10
  3. Node 7.8.0

編譯器:

  1. python-->Pycharm Ec
  2. node-->Visual Code Studio

以上開發(fā)環(huán)境以及編譯器大家可以自行百度 or google安裝晴音,本文就不一一介紹了。

爬蟲開發(fā)過程

準備

除了以上所說的編譯器以及開發(fā)環(huán)境的配置外握爷,我們還要明確設計爬蟲的目標墩邀,找到抓取的url以及分析目標url的dom結構黍翎。

  1. 目標:抓取糗百熱門段子第一頁中的,所有作者系羞,作者的頭像,以及對應的段子內(nèi)容
  2. url:http://www.qiushibaike.com/
  3. dom結構:
    可以進入糗百首頁鸭叙,然后查看一下網(wǎng)頁源碼
{690D4AFF-447F-E481-B455-CDF6DAF63F7C}.png

如上圖中所示觉啊,可以看到每個完整的段子都是在class=article block untagged mb15div下面。西面接著找一下對應作者的頭像以及姓名的節(jié)點![](//pic.qiushibaike.com/system/avtnew/2883/28831688/medium/2017051108472215.JPEG)可以看到作者的名字是和imgalt一樣的因此只需要找到這個節(jié)點就可以得到姓名和頭像地址了沈贝。最后看下段子的內(nèi)容杠人,在class= contentdiv下面的span中。至此所有要的信息的節(jié)點都找到了。

爬蟲書寫過程

框架分為五個個部分:爬蟲入口嗡善,url管理器辑莫,html下載器,html解析器罩引,html輸出器

爬蟲入口

新建spider_main.py

from baike import url_manager, html_download, html_parser, html_output


class SpiderMain(object):
    def __init__(self):
        self.urls = url_manager.UrlManager()
        self.download = html_download.HtmlDown()
        self.parser = html_parser.HtmlParser()
        self.out = html_output.HtmlOutput()

    def crow(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_count = self.download.download(new_url)
                data = self.parser.parser(html_count)
                self.out.collect_data(data)
                if count == 1000:
                    break
                count = count+1
            except:
                print 'craw failed:'
        self.out.output_html()



if __name__ == '__main__':
    root_url = 'http://www.qiushibaike.com/'
    obj_spider = SpiderMain()
    obj_spider.crow(root_url)

url管理器

class UrlManager(object):

    def __init__(self):
        self.new_urls = set()
        self.older_urls = set()

    def add_new_url(self, url):
        if url is None:
            return
        if url not in self.new_urls and url not in self.older_urls:
            self.new_urls.add(url)

    def add_new_urls(self, urls):
        if urls is None or len(urls) == 0:
            return
        for url in urls:
            self.add_new_url(url)

    def has_new_url(self):
        return len(self.new_urls) != 0

    def get_new_url(self):
        url = self.new_urls.pop()
        self.older_urls.add(url)
        return url

html下載器

import requests


class HtmlDown(object):
    def download(self, url):
        if url is None:
            return None
        response = requests.get(url)
        if response.status_code != 200:
            return None
        return response.text



html解析器

from bs4 import BeautifulSoup


class HtmlParser(object):
    def __init__(self):
        self.items = []

    def parser(self, response):
        if response is None:
            return None
        soup = BeautifulSoup(response, 'html.parser')
        nodes = soup.findAll('div', class_='article block untagged mb15')
        if nodes is None or len(nodes) == 0:
            return None
        for node in nodes:
            image_node = node.img
            image = 'http:' + image_node['src']
            user_name = image_node['alt']
            content_node = node.span.get_text()
            data = {
                'image_url': image,
                'user_name': user_name,
                'content': content_node
            }
            self.items.append(data)
        return self.items

html輸出器

import json

class HtmlOutput(object):
    def __init__(self):
        self.data = []

    def collect_data(self, data):
        if data is None:
            return
        self.data = data

    def output_html(self):
        self.write_to_json(self.data)
        fout = open('output.html', 'w')
        fout.write("<html>")
        fout.write("<body>")
        fout.write("<table>")
        fout.write("<tr>")
        fout.write("<td>name</td>")
        fout.write("<td>image</td>")
        fout.write("<td>content</td>")
        fout.write("</tr>")
        if len(self.data) > 0:
            for item in self.data:
                fout.write("<tr>")
                fout.write("<td>%s</td>" % (item['user_name']).encode('utf-8'))
                fout.write("<td>%s</td>" % (item['image_url']))
                fout.write("<td>%s</td>" % (item['content']).encode('utf-8'))
                fout.write("</tr>")

        fout.write("</table>")
        fout.write("</body>")
        fout.write("</html>")
        fout.close()

    def write_to_json(self, data):
        if data is None:
            return
        f = open('json.txt', 'w')
        json_str = json.dumps(data).encode('utf-8')
        print json_str
        f.write(json_str)
        f.close()


最終將爬去的數(shù)據(jù)以html的形式和Json形式分表保存在當前路徑下面各吨。

只用node書寫簡單的接口

代碼如下:

ar http = require('http');
var rf = require("fs");
var data = rf.readFileSync("/Users/bear/Desktop/workplace/python/baike/json.txt", "utf-8");
console.log(data)
var jsonStr = {
    'code': '1',
    'message': '操作成功',
    "data": {
        'items': JSON.parse(data)
    }
};

var json = JSON.stringify(jsonStr);
console.log(json);
http.createServer(function (req, res) {
    res.writeHead(200);
    res.end(json);
}).listen(1377, "0.0.0.0");
console.log('Server running at http://127.0.0.1:/');        

然后本地瀏覽器打開:localhost:1377就能看到最終的json了

其它

app 端接口的調用可以看下Github上的開源項目

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市袁铐,隨后出現(xiàn)的幾起案子揭蜒,更是在濱河造成了極大的恐慌,老刑警劉巖剔桨,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件屉更,死亡現(xiàn)場離奇詭異,居然都是意外死亡洒缀,警方通過查閱死者的電腦和手機瑰谜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來树绩,“玉大人萨脑,你說我怎么就攤上這事〗确梗” “怎么了渤早?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長砰奕。 經(jīng)常有香客問我蛛芥,道長,這世上最難降的妖魔是什么军援? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任仅淑,我火速辦了婚禮,結果婚禮上胸哥,老公的妹妹穿的比我還像新娘涯竟。我一直安慰自己,他們只是感情好空厌,可當我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布庐船。 她就那樣靜靜地躺著,像睡著了一般嘲更。 火紅的嫁衣襯著肌膚如雪筐钟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天赋朦,我揣著相機與錄音篓冲,去河邊找鬼李破。 笑死,一個胖子當著我的面吹牛壹将,可吹牛的內(nèi)容都是我干的嗤攻。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼诽俯,長吁一口氣:“原來是場噩夢啊……” “哼妇菱!你這毒婦竟也來了?” 一聲冷哼從身側響起暴区,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤闯团,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后颜启,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體偷俭,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年缰盏,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片淹遵。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡口猜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出透揣,到底是詐尸還是另有隱情济炎,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布辐真,位于F島的核電站须尚,受9級特大地震影響,放射性物質發(fā)生泄漏侍咱。R本人自食惡果不足惜耐床,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望楔脯。 院中可真熱鬧撩轰,春花似錦、人聲如沸昧廷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽木柬。三九已至皆串,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間眉枕,已是汗流浹背恶复。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工娇唯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人寂玲。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓塔插,卻偏偏與公主長得像,于是被迫代替她去往敵國和親拓哟。 傳聞我的和親對象是個殘疾皇子想许,可洞房花燭夜當晚...
    茶點故事閱讀 44,941評論 2 355

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