爬虫实战(五)之 Scrapy 验证码登录 豆瓣 并爬取用户信息

随着反爬的技术深入,特别是有关验证码返回,这对与初学者来说无疑是遇到了悬崖,原本想开开心心的登录某个网站并爬取自己需要的信息,可没想到有些网站当你在某一段时间连续登陆几次之后他就返回验证码验证一下是不是人工所为,这对于初学者来说无疑是拨了一盘冷水,网站之所以这样做无非就是防止爬虫爬取他的信息,那么作为爬虫的开发者,我们就是使用爬虫去爬去他的信息,也就是说我们爬虫者是时时刻刻都在和个站站长斗智斗勇;好了,说了那么多,我们开始进入正题吧:今天的任务就是 登录豆瓣之后爬取里面的个人发布过的日记信息-日记标题、标题链接、发布时间、日记内容等
在开始之前,我们先了解下当遇到验证码时,在实际项目中我们有哪些处理方式,直说了,一般有三种方式:

1) 手动输入验证码
2) 通过编写程序自动识别验证码-(这里会涉及到人工智能的图像识别)
3) 通过一些打码接口实现,比如打码兔等平台,让别人通过接口帮我们输入验证码,但是需要支付一定的费用

在此,我们将以第一种方式进行讲解案例的使用,首先,我们来到豆瓣官网的登录界面:https://accounts.douban.com/login?alias=&redir=https%3A%2F%2Fwww.douban.com%2F&source=index_nav&error=1001,此时不同浏览器会有不同的提示,如果有一行提示语点击“登录”超链接即可来到登录页面,然后输入一个错误的账户(为了看到深层的登录链接以及登录参数),效果图如下:
18.png
从这个效果图中显示没有验证码,这很正常,因为网站只有怀疑我们是爬虫时才返回的,然后我们把隐藏的post请求的连接复制一份粘贴到网址中访问,此时可能会出现有验证码的登录页面,然后查看源码会有以下效果图:
19.png
接着我们输入一个正确的用户名和密码以及验证码(注意:此时是需要开发开发者模式的),成功登陆之后我们找到 post 请求的链接并点击,如图:
20.png
我们登陆成功后会自动跳转到主页,其链接为:https://www.douban.com/people/178279892/,效果图如下:
30.png
因为我们待会儿需要跳转到日记页面中获取发布过的日记信息,因此我们必须想办法获取上图中的日记页面链接,经过观察,我们可以通过 xpath 表达式获取:
//a[@id="usr-profile-nav-notes"]/@href
先观察到这里,接下来我们先创建一个爬虫项目先,使用创建的命令为:scrapy startproject doubanloginproject
然后基于 basic 模板创建一个爬虫文件,命令为: scrapy genspider -t basic doubanspider douban.com
首先我们打开 items.py 定义我们需要存放数据的变量:
import scrapy

class DoubanloginprojectItem(scrapy.Item):
    name = scrapy.Field() #日记标题
    href = scrapy.Field() #日记标题链接
    time = scrapy.Field() #日记发布时间
    content = scrapy.Field() #日记内容

根据以上效果图的分析,我们开始编写我们的爬虫文件:
# -*- coding: utf-8 -*-
import scrapy
import urllib.request
# from scrapy.http import FormRequest
from doubanloginproject.items import DoubanloginprojectItem

#知乎-会话:https://www.zhihu.com/question/54773510

class DbloginspiderSpider(scrapy.Spider):
    name = 'dbloginspider'
    allowed_domains = ['douban.com']
    start_urls = ['https://accounts.douban.com/login']

    def parse(self, response):
        #首先获取验证图片地址并复制给 imgurl 变量
        imgurl = response.xpath('//img[@id="captcha_image"]/@src').extract()
        #由于验证码时有时无,因此需要判断如果有就手动输入
        if len(imgurl) > 0:
            print("有验证码返回...")
            #将验证图片保存到本地中
            local_path = r"C:/Users/Administrator/Desktop/yanzhangma/lcy.png"
            urllib.request.urlretrieve(imgurl[0], filename=local_path)
            #定义接受验证码变量
            capt_value = input("请查看本地 lcy.png 图片并输入对应的验证码-> ")
            #设置带有验证码的 post 信息
            data = {
                "redir":"https://www.douban.com/people/178279892/",#要跳转的链接
                "form_email":"12345678@163.com",#用户名
                "form_password":"luchangyin",#密码
                "captcha-solution":capt_value,#验证码
            }

        else:#此时不需要验证码
            print("无验证码登录...")
            #设置无验证码请求的参数
            data = {
                "redir":"https://www.douban.com/people/178279892/",#要跳转的链接
                "form_email":"12345678@163.com",#用户名
                "form_password":"luchangyin",#密码
            }

        print("登录中......")
        #带参的登录请求
        return [scrapy.FormRequest.from_response(response,
                    #设置 cookie 信息   注:这两项在 settings.py 文件中设置即可
                    #meta={"cookiejar":response.meta["cookiejar"]}, #如果重写 start_requests()方法,那么该值必须对应请求里的 meta 中的键
                    #设置请求头模拟成浏览器
                    #headers=self.headers,
                    #设置 post 表单中的数据
                    formdata=data,
                    #设置回调函数
                    callback=self.mynode,
                    )]



    #之所以创建这个方法是因为如果直接打开日记链接:https://www.douban.com/people/178279892/notes 的话,不需要 cookie 也可以访问,因此为看到 cookie 的效果我们定义该方法 
    def mynode(self, response):
        #获取用户名
        my_name = response.xpath(r'//div[@class="info"]/h1/text()').extract_first()
        #获取日记页面的链接
        note_url = response.xpath(r'//a[@id="usr-profile-nav-notes"]/@href').extract_first()
        #回调方法处理的是请求之后的数据
        return scrapy.Request(note_url, callback = self.next)



到这里的话,为了验证登录之后会怎么样,建议妳在 mynode() 方法中不要就那么快的去请求日记界面链接,最好先把响应结果先存到本地的 html 中,然后打开看有木有数据,在这里我就不做演示了;接下来我们继续,看看日记页面需要怎样获取相应的信息,看图:
31.png
通过以上方法的请求跳转,我们来到了日记数据页面,根据效果图的分析结果,我们再写个方法获取日记信息:
    #获取日记信息方法
    def next(self, response):
        print("......此时已经登录完成并爬去了个人中心的日记数据......")
        #获取日记选项列表
        data_list = response.xpath(r'//div[@class="note-container"]')
        item = DoubanloginprojectItem() #获取实体对象
        for data in data_list:
            item["name"] = data.xpath(r'./div[1]/h3/a/text()').extract() #日记标题
            item["href"] = data.xpath(r'./div[1]/h3/a/@href').extract() #日记链接
            item["time"] = data.xpath(r'./div[1]/div/span/text()').extract()#日记发布时间
            item["content"] = data.xpath(r'./div[3]/text()').extract() #日记内容

            yield item


到目前为止,爬虫文件搞定了,为了以防万一,建议在循环中先输出下数据看看有木有值,这里不做演示;好了,爬虫文件搞定之后接下来我们就要对这些数据进行处理,自当来到管道文件 pipelines.py :
import csv

class DoubanloginprojectPipeline(object):

    def __init__(self):
        self.f = open("doubannote.csv", "w")
        self.writer = csv.writer(self.f)
        self.writer.writerow(['日记标题', '日记链接', '日记发布时间', '日记内容'])


    def process_item(self, item, spider):
        #循环写入本地文件
        for i in range(0, len(item["name"])):
            #保存为csv文件
            dbnote_list = [item["name"][i], item["href"][i], item["time"][i], item["content"][i]]
            print("管道文件测试-> %s"%dbnote_list)#输出测试
            self.writer.writerow(dbnote_list)

        return item


    def close_spider(self, spider):
        self.f.close()



最后一步,别忘了在配置文件中启动管道以及相应信息的设置哦:
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#模拟浏览器
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36'

# Obey robots.txt rules 不遵循网站规则
ROBOTSTXT_OBEY = False

# Disable cookies (enabled by default)  打开 cookie,当然默认是打开的
COOKIES_ENABLED = True

#启动管道文件
ITEM_PIPELINES = {
   'doubanloginproject.pipelines.DoubanloginprojectPipeline': 300,
}


万事俱备,我们开始破东风吧,执行爬虫文件:scrapy crawl dbloginspider --nolog
大致有两种提示:一种是没有验证码,一种是有验证码:
1)无验证码
23.png
2)有验证码
24.png
打开我们本地的 csv 文件:
26.png
图中可以看到爬取下来的表格中的数据后面无意中多了一个空行,只需在管道文件中修改下open()函数即可:
self.f = open("blogs.csv", "w", newline='')   #newline=''去掉多余的空行
欧了,哈哈哈,也不过如此;如果对您有帮助记得给个赞哦(如有问题可以留言),嘿嘿;下一战:爬取拉勾网信息
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,084评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,623评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,450评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,322评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,370评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,274评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,126评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,980评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,414评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,599评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,773评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,470评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,080评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,713评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,852评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,865评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,689评论 2 354

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,097评论 25 707
  • 这两天心口总像是堵着什么东西,难以言语,分外焦虑,难受的想哭,可是最可怕的是你哭都哭不出来…… 马上就可以...
    by1019阅读 201评论 0 0
  • 2017-2-16 DAY2:黑庙白庙一日游,晚餐:hot chilli 昨晚1点半睡觉,早上6点起床洗漱收拾,吃...
    liyin1256阅读 442评论 0 0
  • 【在此阅读其他章节】 唐介岚的第一反应就是转身逃跑,然而他刚刚有所动作,威利就立即堵在了他的面前。逃跑无望,他只好...
    坑爹堂阅读 545评论 1 0
  • 你走的第三十四天,还有79天。我终于熬到了七头了!想你想你想你,今天下班出来给你找了好多礼物,等你生日的时候一起给...
    rainll阅读 240评论 0 0