美文网首页
爬虫实战--模拟登陆

爬虫实战--模拟登陆

作者: 郭彦超 | 来源:发表于2019-12-23 20:01 被阅读0次

并不是所有网站信息都可直接访问,有相当一部分的数据是需要用户授权登陆后才可以拿到的,比如某某网站开通vip会员才能进行下载操作

背景

获取尚德个人主页的课程列表

分析

  • token
    登陆验证一般有两种形式,一种是对方授权你一个具有时效性的token字符串,每次请求时需要带上这个字符串,格式如下
http://aaaa/list.do?token=bbb

每次只需要在对应的url后面拼接对应的token就可以了,当token失效时根据认证接口再次获取就可以了,这种数据API因为走的是http协议,所以具备很强的跨平台优势,一般多用于无页面的数据服务之间的互相请求

  • 认证登陆

认证登陆一般也分两种,一种是需要验证码认证的(之后讲),一种不需要验证码,后者相对比较简单,做法和上面比较类似,不同的是这种是把认证存储到cookie信息里而且需要通过selenium模拟登陆方式获取授权后的cookie信息

代码演示

public class RobotLogin {
    public static void main(String[] args) throws IOException, InterruptedException  {
        //geckodriver配置
        FirefoxBinary firefoxBinary = new FirefoxBinary();
        firefoxBinary.addCommandLineOptions("--headless");
        System.setProperty("webdriver.gecko.driver", "target/classes/drivers/geckodriver.exe");
        //声明使用的是火狐浏览器
        FirefoxOptions firefoxOptions = new FirefoxOptions();
        firefoxOptions.setBinary(firefoxBinary);
        FirefoxDriver driver = new FirefoxDriver(firefoxOptions);
        //使用火狐浏览器打开尚德个人主页
        String url = "http://yi.sunlands.com/ent-portal-war/new_pt_uc/my_lesson/lessonHome.action?auth=true&ticket=ST-417335-WD7Vp4cViOIaCiW6uHxd-cas";
        driver.get(url);
        //元素定位,提交用户名以及密码
        driver.findElementByName("username").clear();  //清空后输入
        driver.findElementByName("username").sendKeys("bbb");
        driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
        driver.findElementById("password").clear(); //清空后输入
        driver.findElementById("password").sendKeys("***");
        //元素定位,点击登陆按钮
        driver.findElementById("msgBtn").click();
        Thread.sleep(5*1000);  //休息一段时间,使得网页充分加载。注意这里非常有必要
        Set<Cookie> cookies = driver.manage().getCookies();
        //获取登陆的cookies
        String cookieStr = "";
        for (Cookie cookie : cookies) {
            cookieStr += cookie.getName() + "=" + cookie.getValue() + "; ";
        }
        System.out.println(cookieStr);
        //基于Jsoup,使用cookies请求个人信息页面
        Document doc = Jsoup   //添加一些header信息
                .connect(url)
                .header("Host", "yi.sunlands.com")
                .header("Connection", "keep-alive")
                .header("Cache-Control", "max-age=0")
                .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3")
//                .header("Origin", "http://www.******.com")
                .header("Referer", "http://yi.sunlands.com/")
                .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0")
                .header("Content-Type", "application/x-www-form-urlencoded")
                .header("Accept-Encoding", "gzip, deflate, br")
                .header("Upgrade-Insecure-Requests", "1")
                .cookie("Cookie", cookieStr)
                .get();
        System.out.println(doc.html());
        //解析数据
        org.jsoup.select.Elements elements = doc.select("div[class=side-nav]")
                .select("ul[class=classify]");
        for (Element element : elements) {
             System.out.println(element.select("a").text());
        }
        driver.quit();  // 关闭浏览器
    }
}

改进

使用selenium实现的,为了减少依赖和保障后期的爬取效率我们也可以不用

  • 首先分析登录页面结构
    打开尚德个人登录页面,通过chrom检查定位,不难发现这是一个表单登录

    image.png
  • 通过抓包分析提交参数
    表单提交走的是post请求,当点击完”立即登录”我们通过抓包工具可以看到对应的表单参数


    image.png

这里需要主要的是尚德为了防止别人刷登录页面在这里加了一个登录验证,lt是虽登录页面固定返回的一个隐藏字段(在上面截图可以看到),每次刷新这个字段的值都会不一样,所以需要先爬取登录页面获取lt对应的述职字符串

  • 伪造表单请求
    接下来这一步就是根据组装好的表单参数去请求服务器了,过程就不多说了,直接上一个例子一看便知:
public static void testSDLogin() throws IOException {
        Map<String, String> data = new HashMap<>();
        data.put("execution","e1s1");
        data.put("_eventId","submit");
        data.put("username","aaa");
        data.put("password","**");
        data.put("sign","");
        data.put("isgw","");

        Map<String,String> headerMap = new HashMap<String, String>();
        headerMap.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36");
        headerMap.put("Content-Type", "application/json; charset=utf-8");


        Document doc = Jsoup.connect("http://passport.sunlands.com/login")
                .headers(headerMap).ignoreContentType(true)
                .timeout(5000).get() ;

        String lt = doc.select("div[id=loginUserDiv]").select("input[name=lt]").attr("value");
        System.out.println(lt);
        data.put("lt",lt);

        Document doc2 = Jsoup.connect("http://yi.sunlands.com/ent-portal-war/new_pt_uc/my_lesson/lessonHome.action?auth=true&ticket=ST-611339-ftbcmMbB5x41xTJnrnDc-cas")
                .headers(headerMap).ignoreContentType(true)
                .data(data)
                .method(Connection.Method.POST)
                .timeout(5000).post() ;
        System.out.println(doc2.html() );
         
    }

小结

以上例子仅供学习参考,转发请注明出处

相关文章

  • 爬虫实战--模拟登陆

    并不是所有网站信息都可直接访问,有相当一部分的数据是需要用户授权登陆后才可以拿到的,比如某某网站开通vip会员才能...

  • 模拟登陆存在问题

    学习Python爬虫(七)--Scrapy模拟登录的post模拟登陆后,自己写了模拟登陆知乎首页的代码。 测试后发现无效

  • Scrapy基础——Cookies和Session

    我在Python爬虫基础-模拟登陆曾经谈过Cookies和Session。那么如何我想使用Scrapy进行模拟登陆...

  • 爬虫实战之Scrapy模拟登陆

    想爬取网站数据?先登录网站!对于大多数大型网站来说,想要爬取他们的数据,第一道门槛就是登录网站。下面请跟随我的步伐...

  • Selenium+ PhantomJS+Requests 综合使

    关键字: Python 爬虫 PhantomJS MongoDB Webdriver 模拟登陆 Fiddler ...

  • Python网络爬虫之模拟登陆

    为什么要模拟登陆? Python网络爬虫应用十分广泛,但是有些网页需要用户登陆后才能获取到信息,所以我们的爬虫需要...

  • Scrapy爬虫模拟登陆豆瓣

    首先还是创建爬虫,其命令如下: 模拟登陆豆瓣的关键点1、分析真实post地址,寻找formdata;2、模拟pos...

  • java模拟登陆

    java爬虫 模拟登陆CSDN 抓包得到post请求的5个参数: username:139******027@16...

  • 用于pixiv漫画下载的爬虫

    GitHub - mtclaw/pixivSpider: 根据p站号下载漫画的爬虫。 # 关于模拟登陆 本来是想自...

  • Python爬虫基础-模拟登陆

    为什么我们要让爬虫模拟登陆呢? 有些内容只有登陆才能进行爬取,如知乎,不登录的主页只能看到注册和登陆 ; 你想爬取...

网友评论

      本文标题:爬虫实战--模拟登陆

      本文链接:https://www.haomeiwen.com/subject/hazznctx.html