相关推荐recommended
爬虫百度返回“百度安全验证”终极解决方案
作者:mmseoamin日期:2023-12-05

这篇文章也可以在我的博客查看

爬不了啊!!

最近一哥们跟我说百度爬虫爬不了

弹出:“百度安全验证”,“网络不给力,请稍后重试”

说到爬虫,这里指的是Python中最常用的requests库

我说怎么爬不了了?

  • user-agent加了吗?
  • cookie加了吗?

    他说都加了

    我不信邪,试了一下,超,真的返回百度安全认证:

    
    
    
        
        百度安全验证
        
    
    
        
    网络不给力,请稍后重试

    问题反馈

    网络有说加Accept header的,我试了,也不行。

    我的代码是这样的:

    import requests
    headers={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36',
    'Accept-Encoding': 'gzip, deflate, br',
    'Cookie': '[yummy cookies ^_^]',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7'
    }
    response = requests.get('https://baidu.com/s', headers=headers)
    response.encoding = 'utf-8'
    print(response.text)
    

    我纳闷了,怎么回事呢?

    考虑到爬虫其实也是访问网站的过程

    此时应该使用fiddler的Composer对需要爬取的报文进行调试

    通过不断地增加、减少header项,最终得出必要的headers

    到最后,发现请求百度所必须的数据其实只有:

    以下是Fiddler Composer的raw输入

    GET https://xueshu.baidu.com/s?wd=%E5%9B%BE%E5%83%8F%E9%87%8D%E5%BB%BA%E3%80%81%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0 HTTP/1.1
    Host: xueshu.baidu.com
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36
    Accept-Encoding: gzip, deflate, br
    Cookie: [yummy cookies ^_^]
    

    也就是:

    • User-Agent
    • Cookie
    • Accept-Encoding

      但是……我之前的代码已经包含这些了啊?还赠送了一个Accept呢?

      分析真正问题

      这是我突然意识到一个事儿……

      说到底,Fiddler不也是机器人吗?

      为啥Fiddler能发出去,但Python的requests发不出去啊

      难道是requests被抓到小鸡脚了吗?

      一波考虑之后 感觉有可能

      Fiddler虽然也是机器人,但它作为一个流量转发工具,它很完善,行为更像浏览器

      而requests相反,它本来就不是用作浏览器访问,而是以最轻便方式执行http请求

      其中可能某些浏览器应有的行为,被requests阉割掉了,然后被百度识别出来了

      爆破

      好吧,但不管怎样,你百度还是需要提供服务的

      requests虽然因为不是浏览器被你识别出来了,那我用浏览器访问你,你又该如何应对?

      因此祭出爬虫的宇宙终极答案:无头浏览器

      Selenium

      Selenium是一个用于自动化浏览器操作的工具,常用于测试网页应用程序和执行Web任务

      它提供了多种编程语言的客户端库,如Python、Java、C#等,用于控制浏览器的行为

      通过编写代码,可以模拟用户在浏览器中的操作,比如点击链接、填写表单、提交数据等

      OK很好,我们就用Selenium进行爬虫

      安装环境

      Selenium

      我们需要下载python的Selenium库,执行:

      pip install -U selenium
      

      浏览器

      你需要一个真的浏览器以进行网上冲浪,希望你有一个_

      Linux shell玩家也可以安装浏览器

      不过就不在此展开了

      浏览器驱动

      需要安装与你浏览器对应的浏览器驱动(Browse Driver)以供Selenium调用

      这里也不详细展开,但大致分两种做法:

      手动安装

      注意下的是Driver,别下成浏览器本身了

      无非就是到官网下,比如:

      • Chrome的最新版
      • Chrome 114以前
        自动安装

        可以使用webdriver-manager Python库实现自动化安装管理

        pip install webdriver-manager
        

        调用就自动安装,比如Chrome:

        from selenium import webdriver
        from webdriver_manager.chrome import ChromeDriverManager
        driver = webdriver.Chrome(ChromeDriverManager().install())
        

        爬就爬,我最会爬了

        那就给大伙用Selenium爬一个

        编写以下代码,唯一需要注意的就是Driver的路径需要更改(我放到项目根目录了,所以直接写文件名):

        from selenium import webdriver
        from selenium.webdriver.chrome.options import Options
        # 我们并不需要浏览器弹出
        options = Options()
        options.headless = True
        # 启动浏览器的无头模式,访问
        # ========================================
        # 注意:这是Selenium 4.10.0以下写法,高版本见下面
        # ========================================
        driver = webdriver.Chrome('chromedriver.exe', options=options)
        driver.get("https://xueshu.baidu.com/s?wd=图像重建、深度学习")
        # 获取页面的源代码
        page_source = driver.page_source
        # 输出页面源代码
        print(page_source)
        driver.quit()
        

        ❗在Selenium 4.10.0及以上版本,上面的代码会报错:

        TypeError: WebDriver.__init__() got multiple values for argument 'options'
        

        原因是webdriver的函数签名有改变,在高版本中,你需要显式指定service:

        from selenium.webdriver.chrome.service import Service
        s = Service('chromedriver.exe')
        driver = webdriver.Chrome(service=s, options=options)
        

        无头浏览器将会为你操办一切,直接访问到页面

        不仅不需要cookie(在非登录的情况下),甚至连header都不需要

        问题

        你可能会感觉得到,这东西运行起来比requests慢

        我只能说确实,因为它是真浏览器

        但是……你真的需要快吗?

        • 爬虫太快也是会被封IP的
        • 如果你配置了IP池、多线程一系列框架,还需要在乎这点速度差距吗?

          慢还有一个好处,它更像人工行为了,它能难被检测出了,嘻嘻

          那今天的爬虫就到这了,该睡觉了