爬取知乎问题答案赞同最多数据--单线程完整版
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个问题