虽然我是做Android的,但也会用python抓点数据用用

前言

最近也是在工作之余开发一个Android App,采用当前比较火的框架retrofit+rxjava+rxbus+lamda+greenDao+glide等。有兴趣的小伙伴可以关注一下我的github开源项目。本文主要介绍的是如何利用python抓取糗百的热门段子。

开发环境

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

编译器:

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

以上开发环境以及编译器大家可以自行百度 or google安装,本文就不一一介绍了。

爬虫开发过程

准备

除了以上所说的编译器以及开发环境的配置外,我们还要明确设计爬虫的目标,找到抓取的url以及分析目标url的dom结构。

  1. 目标:抓取糗百热门段子第一页中的,所有作者,作者的头像,以及对应的段子内容
  2. url:http://www.qiushibaike.com/
  3. dom结构:
    可以进入糗百首页,然后查看一下网页源码
{690D4AFF-447F-E481-B455-CDF6DAF63F7C}.png

如上图中所示,可以看到每个完整的段子都是在class=article block untagged mb15div下面。西面接着找一下对应作者的头像以及姓名的节点![](//pic.qiushibaike.com/system/avtnew/2883/28831688/medium/2017051108472215.JPEG)可以看到作者的名字是和imgalt一样的因此只需要找到这个节点就可以得到姓名和头像地址了。最后看下段子的内容,在class= contentdiv下面的span中。至此所有要的信息的节点都找到了。

爬虫书写过程

框架分为五个个部分:爬虫入口,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()


最终将爬去的数据以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上的开源项目

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容