Skip to content

API 设计

HugeBridge edited this page Jan 4, 2018 · 15 revisions

API接口设计

1. 数据库设计

  • 使用SQLite3
初始化数据库
init_all_dbs()
存储问题
store_new_question(question)
  • 内容模型封装
class Question(object):

    def __init__(self, ques_id, url, title, description, follower, views, comments, answer_file):
        """
        :param ques_id: 问题ID
        :param url:问题URL
        :param title: 问题标题
        :param description: 问题内容
        :param follower: 问题关注者数量
        :param views: 问题浏览量
        :param comments: 问题评论数
        :param answer_file: 问题回答文件名
        """
        self.questionid = ques_id
        self.title = title
        self.description = description
        self.follower = follower
        self.views = views
        self.comments = comments
        self.answers = answer_file
        self.url = url

class Answer(object):

    def __init__(self, question, name, user_tag, content, ups, comments):
        """
        :param question: 问题内容
        :param name: 回答者昵称
        :param user_tag: 回答者标签
        :param content: 回答内容
        :param ups: 点赞数
        :param comments: 评论数
        """
        self.question = question
        self.name = name
        self.user_tag = user_tag
        self.content = content
        self.ups = ups
        self.comments = comments

class Topic(object):

    def __init__(self, topic_id, title, topic_type, questions, question_user, question_answer, question_comments):
        """
        :param topic_id: 话题 ID
        :param title: 话题标题
        :param topic_type: 话题类型
        :param questions: 问题
        :param question_user: 问题答者
        :param question_answer: 问题回答
        :param question_comments: 问题评论
        """
        self.topic_id = topic_id
        self.title = title
        self.topic_type = topic_type
        self.questions = zip(questions, question_user, question_answer, question_comments)

class Person(object):

    def __init__(self, name, signature, tag, counters, achievements, cares, activities):
        """
        :param name: 用户名
        :param signature: 用户签名
        :param tag: 用户标签
        :param counters: 统计量
        :param achievements: 成就
        :param cares: 关注内容
        :param activities: 活动
        """
        self.name = name
        self.signature = signature
        self.tag = tag
        # 回答数
        self.answer_num = counters[0]
        # 提问数
        self.question_num = counters[1]
        # 文章数
        self.article_num = counters[2]
        # 专栏数
        self.zhuanlan_num = counters[3]
        # 想法数
        self.thoughts_num = counters[4]
        # 收到赞
        self.ups = achievements[0]
        # 感谢数
        self.thanks = achievements[1]
        # 收藏数
        self.collected = achievements[2]
        self.edits = achievements[3]
        # 关注人的数量
        self.following = achievements[4]
        # 被关注的数量
        self.followers = achievements[5]
        # 关注的话题
        self.follow_topics = cares[0]
        # 关注的专栏
        self.follow_zhuanlan = cares[1]
        # 关注的问题
        self.follow_questions = cares[2]
        self.collection = cares[3]
        # 活动
        self.activities = activities
  • 存储文件
def save_file(content_type, content):

"""
:param content_type: 文件类型(问题-question,回答-answer,搜索-search,用户-people)
:param content: 写入内容,已打包成类对象
"""

2. 多线程设计

  • 创建线程管理器
# 创建管理器,func为任务函数
thread_manager = SMThreadManager(max_threads=8, func=func)

# 添加新的任务
"""
:param func: 任务函数
:param args: 任务参数
"""
thread_manager.add_task(func, args)

# 继续上一次任务,任务内容(参数)改变
thread_manager.do(args)

3.网页解析设计

  • 网页分类
按照网页的前缀给要爬取的网页分为四类:

搜索页面: 'https://www.zhihu.com/search' + content
问题页面: 'https://www.zhihu.com/question' + content
人物页面: 'https://www.zhihu.com/people' + content
话题页面: 'https://www.zhihu.com/topic' + content
  • 搜索页面
class SearchParser:

    # 传入爬取的网页内容
    def __init__(self, text):

    # 清理文字间不必要的空格符,换行符和制表符
    def clean(self, text):
   
    # 得到搜索的问题和与其相关的Live,话题和专栏
    def getquestion(self):
    def getlive(self):
    def gettopic(self):
    def getzhuanlan(self): 

    # 得到网页的回答的主体
    def getcontent(self):
    
    # 得到页面包含的url
    def geturl(self):

    # 将得到的内容汇总
    def total(self):
  • 问题页面
class QuestionParser:

    # 传入爬取的网页内容
    def __init__(self, text):

    # 清理文字间不必要的空格符,换行符和制表符
    def clean(self, text):
   
    # 得到问题的标题,内容,关注数,浏览数,评论数和回答数
    def getquestion(self):

    # 得到答案的作者,签名,内容,赞同数和评论数
    def getanswer(self):
    
    # 得到页面包含的url
    def geturl(self):

    # 将得到的内容汇总
    def total(self):
  • 人物页面
class PeopleParser:

    # 传入爬取的网页内容
    def __init__(self, text):

    # 清理文字间不必要的空格符,换行符和制表符
    def clean(self, text):
   
    # 得到人物的姓名,介绍,标签和各种活动信息
    def getinformation(self):

    # 得到人物最近的动态
    def getactivity(self):
    
    # 得到人物的成就信息
    def getachieve(self):

    # 得到人物关注的各种信息
    def getcare(self):

    # 得到页面包含的url
    def geturl(self):

    # 将得到的内容汇总
    def total(self):
  • 话题页面
class TopicParser:

    # 传入爬取的网页内容
    def __init__(self, text):

    # 清理文字间不必要的空格符,换行符和制表符
    def clean(self, text):
   
    # 得到话题的标题
    def gettitle(self):

    # 得到话题的回答类型,问题,回答者姓名和简述,评论数和网页包含的url
    def getinformation(self):
    
    # 将得到的内容汇总
    def total(self):

4. 网页爬取设计

  • 登录知乎
#定义Login类
class Login(object):

    def __init__(self):

    def _init_session(self):

    # 检查登录,若未登录输入账号密码
    def check(self):

    # 获取登录时需要用到的_xsrf
    def _get_xsrf(self):
        return _xsrf[0]

    # 获取验证码
    def _get_captcha(self):
        return captcha
    # 通过查看用户个人信息来判断是否已经登录
    def is_login(self):

#使用方法
login = Login()
login.check()
  • 爬取页面
   # keyword默认为空
   get_html(url, keyword)
  • 更新登录方式
  # 模拟浏览器phantomjs操作登录
  anotherlogin()
   
  • 验证码识别
   # 识别验证码,返回识别值
   capcha_recognition()

5.分布式设计

  • Worker
# 配置参数
config = WorkerConfig(
    name='worker',
    task_batchsize=2,
    crawler_threads=8,
    parser_threads=2,
    authkey=AUTH_KEY,
    address=(ip, 23333)
)
"""
:param crawler_func: 请求函数
:param parser_func: 解析函数
"""
worker = Worker(config=config, crawler_func=crawl_func, parser_func=parse_func)

worker.run()
Clone this wiki locally