美文网首页Python四期爬虫作业
爬取知乎问题答案赞同最多数据--单线程完整版

爬取知乎问题答案赞同最多数据--单线程完整版

作者: chengcxy | 来源:发表于2017-05-05 22:49 被阅读825次

    一、抓取方法稍微调整说明

    上一篇文章,通过给定一个初始的url入口,解析出下一次的json_url请求,进而解析出 搜索框输入【python学习】页面的帖子url,昨天解析时候我看了下url,代码中也对url进行了处理,这个页面有2种帖子,一个是知乎专栏贴,一个是知乎问题贴。

    本想url存库的时候加入一个标识区分是专栏贴和问题帖,由于我们本次作业是抓取回答中赞同数高分的数据,专栏帖和问题贴这两个url的页面布局是不同的,如果要抓取专刊数据 需要另外写一个解析专栏帖子的函数。
    时间关系我先把专栏的url过滤掉,正则表达式修改了下。

    同时对知乎网站做了一下提问测试,从业务上了解下以便数据的抓取。模拟了下知乎提问问题,问题帖url中都有question字符串,并且提问时候需要在标题加问号,提问者可以选择匿名和不匿名,当然回答者也可以选择匿名和不匿名,同时答案如果没有赞同数,则抓取不到,综合考虑到这些我们在取出数据的时候要做下判断,以免程序报错。


    赞同数

    二、完整代码 Scrapy框架代码 稍等 在整理

    #coding:utf-8
    import requests
    import json
    import re
    from lxml import etree
    import time
    from class_mysql import Mysql
    
    #从第一次请求开始 解析返回的json数据中 下一次的json请求url 回调解析json_url
    def start_requests(url):
        html=requests.get(start_url,headers=headers,data=form_data,cookies=cookies).content
        json_data=json.loads(html)['htmls']
        for data in json_data:
            url_data=re.findall(reg,data.encode('utf-8'))
            if len(url_data)>0:
                url=base_url+url_data[0]
                print url
                parse_title_data(url)
        next_req=json.loads(html)['paging']['next']
        print next_req
        next_json_url=base_url+next_req
        parse_json_req_url(next_json_url)
    
    #解析下一次的json_url 和 文章url
    def parse_json_req_url(url):
        html=requests.get(url,headers=headers,cookies=cookies).content
        next_req=json.loads(html)['paging']['next']
        print next_req
        next_json_url=base_url+next_req
        if next_json_url==base_url:
            pass
        else:
            print next_json_url
            parse_title_url(next_json_url)
            #等待3秒 以防止被ban
            time.sleep(3)
            parse_json_req_url(next_json_url)
    
    #对文章url进行正则提取 并拼接处理
    def parse_title_url(url):
        html=requests.get(url,headers=headers,cookies=cookies).content
        json_data=json.loads(html)['htmls']
        for data in json_data:
            url_data=re.findall(reg,data.encode('utf-8'))
            if len(url_data)>0:
                url=base_url+url_data[0]
                print url
                #等待2秒
                time.sleep(2)
                parse_title_data(url)
    
    #文章详情页解析 抓取问题页面内的标题 url 回答者姓名 回答者url(感兴趣可以抓取作者个人信息) 问题关注数 被浏览量 赞同数
    def parse_title_data(url):
        html=requests.get(url,headers=headers,cookies=cookies).content
        selector=etree.HTML(html)
        title = selector.xpath('///h1/text()')[0]
        focus=selector.xpath('//div[@class="NumberBoard-value"]/text()')[0]
        readers=selector.xpath('//div[@class="NumberBoard-value"]/text()')[1]
        #回答者 选择匿名 则 提取不到url连接 和姓名 做下判断
        answer_url=base_url+selector.xpath('//a[@class="UserLink-link"]/@href')[0] if len(selector.xpath('//a[@class="UserLink-link"]/@href'))>0 else '匿名用户'
        answer_name = selector.xpath('//a[@class="UserLink-link"]/text()')[0] if len(selector.xpath('//a[@class="UserLink-link"]/text()'))>0 else '匿名用户'
        agree_num=selector.xpath('//button[@class="Button VoteButton VoteButton--up"]/text()')[0] if len(selector.xpath('//button[@class="Button VoteButton VoteButton--up"]/text()'))>0 else '0'
        print url,title,focus,readers,answer_name,answer_url,agree_num
        item={}
        item[1]=url
        item[2]=title
        item[3] =focus
        item[4] =readers
        item[5] =answer_name
        item[6] =answer_url
        item[7] =agree_num
        #自己的类实例化以后 插入数据
        project.insert(item)
    
    if __name__ == '__main__':
        #定义数据存储字段 
        field_list=['question_url','title','focus','readers','answer_name','answer_url','agree_num']
        field_num=len(field_list)
        #调用自己的类 实例化 
        project=Mysql('zhihu',field_list,field_num)
        #进行建表操作
        project.create_table()
        base_url='https://www.zhihu.com'
        cookies={'q_c1':'2988deeabbf34b628f261ec05af5e5a5|1492963654000|1492963654000',
               'aliyungf_tc':'AQAAABY8vWNx2QYAHDyVPYidDeT0b2nI',
        'acw_tc':'AQAAABPTwzRyxAgAHDyVPYbuuEtON9f4',
        '_xsrf':'1eb2a42b6d2056717efa6095b153f275',
        'r_cap_id':'ZjZiMzllMjVjZTkxNDRmODgzOTA0NWY1OWNlNGJkYWY=|1493904358|0db9d8b43dfb71b86cb6eba64fcc484870c00f5d',
        'cap_id':'NzlkMzk4ZWM3YjA3NDdhNWI2MGJiMDRlMTQyYzJkNzA=|1493904358|110d71e42fabd0101ae75872c12f292729789689',
        'd_c0':'AABCY4v8tAuPTnjZo443WUEQceQaQMecgWk=|1493904359',
        '_zap':'64a52611-0284-4d57-92cc-5de5679490b8',
        'l_n_c':'1',
        's-q':'Python%E5%AD%A6%E4%B9%A0',
        's-i':'4',
        'sid':'qcs07r98',
        '__utma':'51854390.462706417.1493904360.1493904360.1493904360.1',
        '__utmc':'51854390',
        '__utmz':'51854390.1493904360.1.1.utmcsr=baidu|utmccn=(organic)|utmcmd=organic',
        '__utmv':'51854390.100--|2=registration_date=20160317=1^3=entry_date=20160317=1',
        'z_c0':'Mi4wQUhDQVhSblZvQWtBQUVKamlfeTBDeGNBQUFCaEFsVk5DYmt5V1FEYzlUZ1J1VDBlUF9ZMDhaczBJOXVYQmM5UV9R|1493904715|df6483d196e3a5061a92fdba8a0a5cec80936974'
        }
    
        headers={
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36',
        'X-Requested-With':'XMLHttpRequest'
        }
        form_data={'q':'Python学习',
        'correction':'0',
        'type':'content',
        'offset':10
        }
        start_url=base_url+'/r/search?'
        #过滤掉专栏贴 只取问答帖
        reg=r'href="(/question.*?)" class="js-title-link'
        start_requests(start_url)
    

    三、执行情况 存入数据库

    执行存入数据库

    四、数据库数据

    数据库数据

    五、简单分析

    <1>数据去重 本次抓取 python 学习 关键词共99个问题 72位非匿名知乎用户 获赞同数排名

    python学习问答知乎作者排名

    <2> 关注数最高的前10个问题


    关注数最高的前10个问题

    相关文章

      网友评论

      本文标题:爬取知乎问题答案赞同最多数据--单线程完整版

      本文链接:https://www.haomeiwen.com/subject/phostxtx.html