Scrapy爬取知乎所有问题和回答

本文详细介绍了如何使用Scrapy框架模拟登录知乎,爬取所有问题及回答,解析数据并保存到MySQL数据库的过程。文章涵盖登录机制、深度优先爬取问题、分析接口获取回答、异步保存数据以及应对知乎的反爬策略。
摘要由CSDN通过智能技术生成
模拟登录

知乎需要登录才能进入。
所以,爬取知乎的第一步就是模拟登录,这里我们使用的是selenium模拟登录。

start_requests函数是scrapy中spider的入口,所以模拟登录应该放在这个函数中,我们重写start_requests函数:

def start_requests(self):

     from selenium import webdriver
     from selenium.webdriver.chrome.options import Options

     os.system('chcp 65001')
     os.popen('chrome.exe --remote-debugging-port=9222 --user-data-dir="C:\selenum\AutomationProfile"')
     chrome_options = Options()
     chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
     browser = webdriver.Chrome(
         executable_path='F:\BaiduNetdiskDownload\ArticleSpider\chromedriver.exe',
         options=chrome_options)
     browser.get("https://www.zhihu.com/signin")
     browser.find_element_by_css_selector(".SignFlow-accountInput.Input-wrapper input").send_keys("用户名")
     import time
     time.sleep(3)
     browser.find_element_by_css_selector(".SignFlow-password input").send_keys("密码")
     browser.find_element_by_css_selector(
         ".Button.SignFlow-submitButton").click()
     time.sleep(10)
     Cookies = browser.get_cookies()
     print("----",Cookies)
     cookie_dict = {
   }
     for cookie in Cookies:
         cookie_dict[cookie['name']] = cookie['value']
     browser.close()
     
     return [scrapy.Request(url=self.start_urls[0],dont_filter=True,headers=self.headers,cookies=cookie_dict)] #callback默认是parse函数

模拟登录后,获取cookies,并在settings.py中将COOKIES_ENABLED设为True,这样我们就只需要在第一次请求中加上cookies,后面的所有请求都会默认带上cookies

COOKIES_ENABLED = True

另外,记得携带请求头,不然会被知乎识别为爬虫。

爬取所有的问题

由于知乎没有提供所有问题的入口,所以我们采用的是深度优先的爬取算法

模拟登录后,我们在parse函数中解析所有的问题url
经过分析,我们发现问题url的格式为:https://www.zhihu.com/question/问题id

使用filter函数过滤掉非https开头的url,过滤后的url如果是/question/***格式, 就提交给下载器,如果不是,则进一步解析跟踪。

def parse(self, response):
     '''
     提取出html页面中所有的url  并跟踪这些url进一步爬取
     如果提取的格式为/question/*** 就提交给下载器
     '''
     all_urls = response.xpath('//a/@href').extract()
     all_urls = [parse.urljoin(response.url,url) for url in all_urls]
     all_urls = filter(lambda x: True if x.startswith('https') else False,all_urls)  #过滤掉非https开头的url
     for url in all_urls:
         match_obj = re.match('(.*zhihu.com/question/(\d+))(/|$).*',url)
         if match_obj:
             #如果url格式为question格式,则下载后解析页面
             request_url = match_obj.group(1)
             request_id = match_obj.group(2)
             yield scrapy.Request(request_url,headers=self.headers,meta={
   "zhihuid":request_id},callback=self.parse_question)
         
Python 模拟虫抓取知乎用户信息以及人际拓扑关系,使用scrapy虫框架,数据存储使用mongo数据库。   本地运行请注意:虫依赖mongo和rabbitmq,因此这两个服务必须正常运行和配置。为了加快下载效率,图片下载是异步任务,因此在启动虫进程执行需要启动异步worker,启动方式是进入zhihu_spider/zhihu目录后执行下面命令:   celery -A zhihu.tools.async worker --loglevel=info   虫项目部署:   进入zhihu_spider后执行```docker-compose up``` ,进入container后和本地运行方法相同,依次启动mongo、rabbitmq、异步任务、虫进程即可。   其它需要说明的问题:   虫框架从start\_requests开始执行,此部分会提交知乎主页的访问请求给引擎,并设置回调函数为post_login.   post\_login解析主页获取\_xsrf保存为成员变量中,并提交登陆的POST请求,设置回调函数为after\_login.   after\_login拿到登陆后的cookie,提交一个start\_url的GET请求给虫引擎,设置回调函数parse\_people.   parse\_people解析个人主页,一次提交关注人和粉丝列表页面到虫引擎,回调函数是parse\_follow, 并把解析好的个人数据提交虫引擎写入mongo。   parse\_follow会解析用户列表,同时把动态的人员列表POST请求发送只引擎,回调函数是parse\_post\_follow,把解析好的用户主页链接请求也发送到引擎,人员关系写入mongo。   parse\_post\_follow单纯解析用户列表,提交用户主页请求至引擎。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值