Python四期爬虫作业

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

2017-05-05  本文已影响825人  chengcxy

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

上一篇文章,通过给定一个初始的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个问题
上一篇下一篇

猜你喜欢

热点阅读