---恢复内容开始---

spiders 文件夹下新建zhihu.py文件(从dos窗口中进入虚拟环境,再进入工程目录之后输入命令 scrapy genspider zhihu www.zhihu.com)

#zhihu.py

import scrapy

import re

import json

from Item import ZhihuQuestionItem,ZhihuAnswerItem

import datatime

from scrapy.loader import ItemLoader

try:

  import urlparse as parse

except:

  from urllib import parse

class ZhuhuSpider(scrapy.Spider):

  name='zhihu'

  allow_domains=["www.zhihu.com"]

  start_urls=["http://www.zhihu.com/"] 

  headers={

  "HOST":"www.zhihu.com",

  "Referer":"https://www.zhihu.com",

  "User-Agent":"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36"

  }

  start_answer_url="https://www.zhihu.com/api/v4/questions/{0}/answers?      sort_by=default&include=data%5B%2A%5D.is_normal%2Cis_sticky%2Ccollapsed_by%2Csuggest_edit%2Ccomment_count%2Ccollapsed_counts%2Creviewing_comments_count%2Ccan_comment%2Ccontent%2Ceditable_content%2Cvoteup_count%2Creshipment_settings%2Ccomment_permission%2Cmark_infos%2Ccreated_time%2Cupdated_time%2Crelationship.is_author%2Cvoting%2Cis_thanked%2Cis_nothelp%2Cupvoted_followees%3Bdata%5B%2A%5D.author.is_blocking%2Cis_blocked%2Cis_followed%2Cvoteup_count%2Cmessage_thread_token%2Cbadge%5B%3F%28type%3Dbest_answerer%29%5D.topics&limit={1}&offset={2}"  #question 第一页answer请求的url

def parse(self,response):

  """

  提取出html页面中的所有url,并跟踪这些url进行进一步爬取

  如果提取出的url中格式为/requestion/xxx,就下载之后直接进入解析函数

  """

  all_urls=response.css("a::attr(href)").extract()

  all_urls=[parse.urljoin(response.url,url) for url in all_urls]

  all_urls=fliter(lambda x:True if x.startswith("https") else False,all_urls)

  for url in all_urls:

    match_obj=re.match("(.*zhihu.com/requestion/(\d))(/|$).*",url)

    if match_obj:

  #如果提取到requestion相关页面,交由parse_question进行解析

      request_url=match_obj.group(1)

      yield scrapy.Request(request_url,headers=self.headers,callback=self.parse_question)

    else:

  #如果未提取到相关页面,则直接进一步跟踪

      yield scrapy.Request(url,headers=self.headers,callback=self.parse)

def parse_question(self,response):

  #处理question页面,从页面中提取出具体的question item

  match_obj=re.match("(.*zhuhu.com/question/(\d))(/|$).*",response.url)

  if match_obj:

     question_id=int(match_obj.group(2))

  item_loader=ItemLoader(item=zhuhuQuestionItem(),response=response)

  if "QuestionHeader-title" in response.text:  #处理新版本  

     item_loader.add_css("title","h1.QuestionHeader-title::text")

     item_loader.add_css("content",".QuestionHeader-detail")

     item_loader.add_value("url",response.url)

     item_loader.add_value("zhuhu_id",question_id)

     item_loader.add_css("answer_num",".List-headerText span::text")

     item_loader.add_css("comment_num",".QuestionHeader-actions button::text")

     item_loader.add_css("watch_user_num",".NumberBoard-value::text")   

     item_loader.add_css("topic",".QuestionHeader-topics .Popover div::text")     

  else:  #处理旧版本页面item的提取

    item_loader.add_xpath("title","//*[@id='zh-question-title']/h2/a/text()|//*[@id='zh-question-title']/h2/span/text()")

    item_loader.add_css("content","#zh-question-detail")

    item_loader.add_value("url",response.url)

    item_loader.add_value("zhuhu_id",question_id)

    item_loader.add_css("answer_num", "#zh-question-answer-num::text")

    item_loader.add_css("comment_num","#zh-question-meta-wrap a[name='addcomment']::text")

    item_loader.add_xpath("watch_user_num","//*[@id='zh-question-side-header-wrap']/text()|//*[@class='zh-question-followers-sidebar']/div/a/strong/text()")

    item_loader.add_css("topic",".zm-tag-editor-labels a::text") 

  question_item=item_loader.load_item()

  yield scrapy.Request(self.start_answer_url,format(question_id,20,0),headers=self.headers,callback=self.parse_answer)

  yield question_item

def  parse_answer(self,response):

   #处理question中的answer

  ans_json=json.load(response.text)

  is_end=ans_json["paging"]["is_end"]

  next_url=ans_json["paging"]["next"]

  #提取answer的具体字段

  for answer in ans_json["data"]:

    answer_item=ZhihuAnswerItem()

    answer_item["zhihu_id"]=answer["id"]

    answer_item["url"]=answer["url"]

    answer_item["question_id"]=answer["question"]["id"]

    answer_item["author_id"] = answer["author"]["id"] if "id" in answer["author"] else None

    answer_item["content"] = answer["content"] if "content" in answer else None

    answer_item["praise_num"]=answer["voteup_count"]

    answer_item["comment_num"]=answer["comment_count"]

    answer_item["creat_time"]=answer["created_time"]

    answer_item["update_time"]=answer["update_time"]

    answer_item["crawl_time"]=datatime.datatime.now()   

    yield answer_item

    if not is_end:

      yield scrapy.Request(next_url,headers=self.headers,callback=self.answer.parse_answer) 

#重写start_Request方法

def start_requests(self):

  return [scrapy.Request("https://www.zhihu.com/#signin",headers=self.headers,callback=self.login)]  #使用scrapy.Request一定要使用回调函数,否则会默认回调parse(self,response)

def login(self,response):

  response_text=response.text

  match_obj=re,match(' .*name="_xsrf" value="(.*?)" ',response_text,re.DOTALL)  #注意使用单双引号

  xsrf=""

  if match_obj:

    xsrf=(match_obj.group(1))

  if xsrf:

    post_url="https://www.zhihu.com/login/phone_num"

    post_data={

      "_xsrf"  :  xsrf,

      "phone_num"  :  "18282902586",

      "password"  :  "admin123"

    }

    return [scrapy.FormRequest(

      url=post_url,

      formdata=post_data,

      headers=self.headers,

      callback=self.check_login

      )]

def check_login(self,response):

  text_json=json.loads(response.text)

  if "msg" in text_json and text_json["msg"]=="登陆成功":

    for url in self.start_urls:

      yield scrapy.Request(url,dont.fliter=True,headers=self.headers)

---恢复内容结束---

scrapy模拟知乎登录(无验证码机制)的更多相关文章

  1. (转)request模拟知乎登录(无验证码机制

    原文:http://www.itnose.net/detail/6755805.html import request try: import cookielib #python2版本 except: ...

  2. request模拟知乎登录(无验证码机制)

    import request try: import cookielib #python2版本 except: import http.cookiejar as cookielib #python3版 ...

  3. htmlunit 模拟登录 无验证码

    1.模拟登录csdn,最开始的时候使用的是httpclient,网上的所有模拟登录csdn的版本都是找到lt/execution/event_id.连同用户名及密码 一起发送即可,但是目前的csdn的 ...

  4. 使用selenium模拟知网登录

    之前都是用phantomjs和selenium模拟浏览器动作的,后来phantomjs不再更新,就转用chrome了 本次模拟登录的网站是中国知网http://login.cnki.net/login ...

  5. Python模拟知乎登录

    # -*- coding:utf-8 -*- import urllib import urllib2 import cookielib import time from PIL import Ima ...

  6. 8-python模拟登入(无验证码)

    方式: 1.手动登入,获取cookie 2.使用cookielib库 和 HTTPCookieProcessor处理器 #_*_ coding: utf-8 _*_ ''' Created on 20 ...

  7. 新版知乎登录之post请求

    前言 在上一篇文章中给大家讲解了requests发送post请求的几种方式,并分析了一些使用陷阱. 疑惑 在文章发表之后,有朋友给我留言说,知乎登录就没有使用提交Form表单(application/ ...

  8. python爬虫scrapy框架——人工识别知乎登录知乎倒立文字验证码和数字英文验证码

    目前知乎使用了点击图中倒立文字的验证码: 用户需要点击图中倒立的文字才能登录. 这个给爬虫带来了一定难度,但并非无法解决,经过一天的耐心查询,终于可以人工识别验证码并达到登录成功状态,下文将和大家一一 ...

  9. 利用scrapy模拟登录知乎

    闲来无事,写一个模拟登录知乎的小demo. 分析网页发现:登录需要的手机号,密码,_xsrf参数,验证码 实现思路: 1.获取验证码 2.获取_xsrf 参数 3.携带参数,请求登录 验证码url : ...

随机推荐

  1. nvm版本管理工具安装

    windows 安装nvm步骤(shi'yongnvm-windows管理node版本): 瞎几把前言:mac上可以用n来管理node版本,私以为n很好用.家里的win7台式机一直没有安装过任何管理工 ...

  2. 网络流——poj1273(入门)

    题目链接:排水沟 题意:现有n个排水沟和m个点(其中1是源点,m是汇点),给定n个排水沟所连接的点,求从源点到汇点的最大流量. [EK解法] #include <algorithm> #i ...

  3. CodeForces Round #521 (Div.3) D. Cutting Out

    http://codeforces.com/contest/1077/problem/D You are given an array ss consisting of nn integers. Yo ...

  4. nginx1.10.3+php5.6+mysql5.7.0

    第一步安装nginx1.10.3 优化nginx的介绍:jemalloc https://ideas.spkcn.com/software/os/linux/577.html 预先安装autoconf ...

  5. Anaconda使用入门

    简介 Conda是一个开源的包.环境管理器,可以用于在同一个机器上安装不同版本的软件包及其依赖,并能够在不同的环境之间切换 Anaconda包括Conda.Python以及一大堆安装好的工具包,比如: ...

  6. 【python】python中的定义类属性和对像属性

    python中变量是没有类型的可以绑定任意类型,但是在语法上不能声明变量. 那我们怎麽来声名一个变量呢? f=None 这样我们给着个变量绑定了以各None类型,我们随时可用重新绑定其它类型.这样我们 ...

  7. 2017北大校赛 J题 pairs

    题目链接 http://poj.openjudge.cn/practice/C17J/ orz 原来是一道无脑枚举题目 只是很卡常数而已 复杂度算错也是很醉orz 当时怎么没想着优化常数呢 题解:枚举 ...

  8. 洛谷 P4168 [Violet]蒲公英 解题报告

    P4168 [Violet]蒲公英 题目背景 亲爱的哥哥: 你在那个城市里面过得好吗? 我在家里面最近很开心呢.昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多 ...

  9. Codeforces Round #520 (Div. 2) A. A Prank

    A. A Prank time limit per test   1 second memory limit per test    256 megabytes 题目链接:https://codefo ...

  10. LA2995 Image is everything

    蓝书P12 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm ...