美文网首页
R爬虫必备——httr+GET请求类爬虫(解螺旋课程)

R爬虫必备——httr+GET请求类爬虫(解螺旋课程)

作者: Clariom | 来源:发表于2020-08-17 16:48 被阅读0次

    前期R爬虫必备—httr+ POST请求类爬虫(网易云课堂)这篇推文主要介绍了httr包如何进行POST请求类爬虫,POST请求往往和异步加载组合出现,有关于异步加载在推文R爬虫必备基础—动态异步加载中也做过介绍。今天呢,主要来讲讲GET请求类爬虫。对于这类请求,往往用rvest、httr或RCurl包都可以,但我们主要还是推荐httr和RCurl。上一期 R爬虫必备基础—rvest为什么不用于动态网页?里已经提过,对于网络请求有限制的网页,尽可能不要使用rvest,因为存在风险。除了极少数静态网页对网络请求完全没有限制外,目前基本上接触的大部分网页或多或少对网络请求都设置。当然在很多情况下,对于这类GET请求类的网页,用rvest包其实也可以成功抓取少量内容,但很容易被封。所以呢,保险点,还是用httr/RCurl吧!

    今天呢,主要就httr包如何开展GET请求类爬虫做简单介绍!首先,先看下httr这个R包中GET函数的大致用法:GET(url = NULL, config = list(), ..., handle = NULL),这里面比较重要的是config参数(设置请求头、cookies和query)。具体参数解释如下:

    • url :the url of the page to retrieve
    • config:Additional configuration settings such as http authentication (authenticate()), additional headers (add_headers()), cookies (set_cookies()) etc. See config() for full details and list of helpers. Further named parameters, such as query, path, etc, passed on to modify_url(). Unnamed parameters will be combined with config().
    • handle:The handle to use with this request. If not supplied, will be retrieved and reused from the handle_pool() based on the scheme, hostname and port of the url. By default httr requests to the same scheme/host/port combo. This substantially reduces connection time, and ensures that cookies are maintained over multiple requests to the same host. See handle_pool() for more details.

    接下来,为了更好理解httr包如何完成一项GET请求类爬虫,下面以解螺旋课程为例做简单介绍!

    解螺旋课程案例说明

    首先进入解螺旋官网(https://www.helixlife.cn/),点击精品课程,然后右击-检查打开浏览器开发工具,点击Network面板,然后ctrl+R刷新,点击第一条信息,发现该网页是个GET请求类。想获取这页信息,对https://www.helixlife.cn/courses/boutique网址走GET请求即可!

    image

    但我们发现精品课程共计4页,想要获取所有的课程信息应该怎么办? 首先,需要分析每个页面的网址,有没有规律,当我们逐条点击不同页面时,发现浏览器开发后台的General中Request URL的变化规律如下:

    https://www.helixlife.cn/courses/boutique?page=1
    https://www.helixlife.cn/courses/boutique?page=2
    https://www.helixlife.cn/courses/boutique?page=3
    https://www.helixlife.cn/courses/boutique?page=4
    

    同时,Query String Parameters的变化规律如下:

    page: 1
    page: 2
    page: 3
    page: 4
    

    在正式爬取之前,需要对下面爬虫主要涉及的参数做下介绍:General里面的Request URL、Request Method、Status Code;Response Headers里面的Content-Type;Request Headers 里面的 Accept、Content-Type、Cookie、Referer、User-Agent等以及最后Query String Parameters里面的所有参数。

    • General里面的Request URL和Request Method方法即是即决定访问的资源对象和使用的技术手段。
    • Response Headers里面的Content-Type决定着你获得的数据以什么样的编码格式返回。
    • Request Headers 里面的 Accept、Content-Type、Cookie、Referer、User-Agent等是你客户端的浏览器信息,其中Cookie是你浏览器登录后缓存在本地的登录状态信息,使用Cookie登入可以避免爬虫程序被频繁拒绝。这其中的参数不一定全部需要提交。
    • Query String Parameters也很重要,是GET请求必备的定位信息,该到哪一页了。
    如何实际操作?

    1. 加载所需要的R包,没安装的提前安装。

    rm(list=ls())
    library("httr") 
    library("magrittr")
    library("rvest")
    library("xml2")
    library("stringr")
    

    2. 首先构造第一页的url。

    url <- c('https://www.helixlife.cn/courses/boutique?page=1')
    

    3. 构造请求提交信息,根据Request headers的内容填写,如下图所示。

    mycookie <- 'Hm_lvt_4b46c1065cade82ef3fa0c6e05cb0f7a=1592799906; XSRF-TOKEN=eyJpdiI6IkEzcWcwZWlhWkJtOGlIWTZWSzZ3V3c9PSIsInZhbHVlIjoiMkxXV3pLbEx3R3lwY2x0SW1tdEh2VGxpSXNjejdDVTVGeFMwV1NrdHpZbkMxSlowcXlnc1J6cVFJdUV2V3dpQiIsIm1hYyI6ImEwZjhjOGZlNTBiMGZmNzdkNmViYTNkNzc4OTM3YzBmZWZlNmFhOTQ0OTAwN2JlNzYzNDQzNjY3MmMzODJmY2YifQ%3D%3D; _session=eyJpdiI6IktaMzFDYTRaOHh6UWM4RmFHYU9yM2c9PSIsInZhbHVlIjoielEzVmRzK0toVzE2Q1dWVjFwSWZZTXRKUEszd3Y5UU9vWFFxV0xUTXNPNk56WkNFcEZ5SHpHTFN0Zk9SNnFGTCIsIm1hYyI6ImU2Mjc2YWI2MGMxY2FkZDA2N2E4NGMwYmRiOTUzOGYwZjQ3NWY1MTg1ZjMyMzk0Zjg0Mjk5OGY1NGU5NTVkODMifQ%3D%3D; SERVERID=3f56386521b609ab6e34c0e5ca694901|1592802688|1592802016; Hm_lpvt_4b46c1065cade82ef3fa0c6e05cb0f7a=1592802695'
    myheaders <- c('accept' ='text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
                   'accept-encoding' = 'gzip, deflate, br',
                   'accept-language' = 'zh-CN,zh;q=0.9',
                   'user-agent' = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36',
                   'cookie' = mycookie)
    
    image

    4. 构造请求头参数信息,根据Query String Parameters内容填写。以下代码是第一页的Query String Parameters参数。

    mypayload <- list("page"= 1)
    
    image.gif

    5. 执行第一页,httr的GET函数,这里用什么函数是由General里的Request Method参数决定的。

    GET(url , add_headers(.headers = 待爬取网页的头部信息),
        set_cookies(.cookies =自己的cookie,
        query = Query String Parameters(构建成特定格式),
        timeout(最大请求时长/秒),
        use_proxy(代理IP)...)
    

    根据GET函数用法,正式进行网络请求,服务器响应返回包含有json格式课程的数据。

    response <- GET(url = url, add_headers(.headers = myheaders), timeout(10), query = mypayload)
    

    这时候通过httr包的GET函数成功请求并获取到网页信息,接下来,交给rvest包进行下游的解析和提取,这方面rvest包更强大。

    url <- c('https://www.helixlife.cn/courses/boutique?page=1')
      mycookie <- 'Hm_lvt_4b46c1065cade82ef3fa0c6e05cb0f7a=1592799906; XSRF-TOKEN=eyJpdiI6IkEzcWcwZWlhWkJtOGlIWTZWSzZ3V3c9PSIsInZhbHVlIjoiMkxXV3pLbEx3R3lwY2x0SW1tdEh2VGxpSXNjejdDVTVGeFMwV1NrdHpZbkMxSlowcXlnc1J6cVFJdUV2V3dpQiIsIm1hYyI6ImEwZjhjOGZlNTBiMGZmNzdkNmViYTNkNzc4OTM3YzBmZWZlNmFhOTQ0OTAwN2JlNzYzNDQzNjY3MmMzODJmY2YifQ%3D%3D; _session=eyJpdiI6IktaMzFDYTRaOHh6UWM4RmFHYU9yM2c9PSIsInZhbHVlIjoielEzVmRzK0toVzE2Q1dWVjFwSWZZTXRKUEszd3Y5UU9vWFFxV0xUTXNPNk56WkNFcEZ5SHpHTFN0Zk9SNnFGTCIsIm1hYyI6ImU2Mjc2YWI2MGMxY2FkZDA2N2E4NGMwYmRiOTUzOGYwZjQ3NWY1MTg1ZjMyMzk0Zjg0Mjk5OGY1NGU5NTVkODMifQ%3D%3D; SERVERID=3f56386521b609ab6e34c0e5ca694901|1592802688|1592802016; Hm_lpvt_4b46c1065cade82ef3fa0c6e05cb0f7a=1592802695'
      myheaders <- c('accept' ='text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
                     'accept-encoding' = 'gzip, deflate, br',
                     'accept-language' = 'zh-CN,zh;q=0.9',
                     'user-agent' = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36',
                     'cookie' = mycookie)
      mypayload <- list("page"= 1)
      response <- GET(url = url, add_headers(.headers = myheaders),query = mypayload, encode="raw")
      #read_html()函数读入并解析网页内容
      web <- read_html(response, encoding ="utf-8")
      #提取课程名称
      course_names <- web %>% html_nodes("div.course-info-container a") %>% html_text()
      #提取课程级别
      course_class <- web %>% html_nodes("span.course-rank") %>% html_text() %>% str_replace_all(" ","") %>% str_replace_all("\n","")
      #提取观看人数
      course_people <- web %>% html_nodes("div.lean-num img") %>% html_attr("alt") 
      #提取课程评分
      course_grade <- web %>% html_nodes("div.course-info-text span.f-l") %>% html_text() %>% str_replace_all(" ","") %>% str_replace_all("\n","") %>% str_replace_all("评分:","")
      course_grade <- course_grade[seq(2,length(course_grade),2)]
      #提取课程价格
      course_price <- web %>% html_nodes("div.course-price") %>% html_text() %>% str_replace_all("¥","")
      #创建数据框存储以上信息
      course <- data.frame(course_names,course_class,course_people,course_grade,course_price)
      course_inf <- rbind(course_inf,course)
    
    1. 执行获取所有页面信息,共4页,利用循环抓取。
    i=1
    course_inf <- data.frame()
    for (i in 1:4){
      url <- c(paste0('https://www.helixlife.cn/courses/boutique?page=',i))
      mycookie <- 'Hm_lvt_4b46c1065cade82ef3fa0c6e05cb0f7a=1592799906; XSRF-TOKEN=eyJpdiI6IkEzcWcwZWlhWkJtOGlIWTZWSzZ3V3c9PSIsInZhbHVlIjoiMkxXV3pLbEx3R3lwY2x0SW1tdEh2VGxpSXNjejdDVTVGeFMwV1NrdHpZbkMxSlowcXlnc1J6cVFJdUV2V3dpQiIsIm1hYyI6ImEwZjhjOGZlNTBiMGZmNzdkNmViYTNkNzc4OTM3YzBmZWZlNmFhOTQ0OTAwN2JlNzYzNDQzNjY3MmMzODJmY2YifQ%3D%3D; _session=eyJpdiI6IktaMzFDYTRaOHh6UWM4RmFHYU9yM2c9PSIsInZhbHVlIjoielEzVmRzK0toVzE2Q1dWVjFwSWZZTXRKUEszd3Y5UU9vWFFxV0xUTXNPNk56WkNFcEZ5SHpHTFN0Zk9SNnFGTCIsIm1hYyI6ImU2Mjc2YWI2MGMxY2FkZDA2N2E4NGMwYmRiOTUzOGYwZjQ3NWY1MTg1ZjMyMzk0Zjg0Mjk5OGY1NGU5NTVkODMifQ%3D%3D; SERVERID=3f56386521b609ab6e34c0e5ca694901|1592802688|1592802016; Hm_lpvt_4b46c1065cade82ef3fa0c6e05cb0f7a=1592802695'
      myheaders <- c('accept' ='text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
                     'accept-encoding' = 'gzip, deflate, br',
                     'accept-language' = 'zh-CN,zh;q=0.9',
                     'user-agent' = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36',
                     'cookie' = mycookie)
      mypayload <- list("page"= i)
      response <- GET(url = url, add_headers(.headers = myheaders),query = mypayload, )
      #读入并解析网页内容
      web <- read_html(response, encoding ="utf-8")
      #提取课程名称
      course_names <- web %>% html_nodes("div.course-info-container a") %>% html_text()
      #提取课程级别
      course_class <- web %>% html_nodes("span.course-rank") %>% html_text() %>% str_replace_all(" ","") %>% str_replace_all("\n","")
      #提取观看人数
      course_people <- web %>% html_nodes("div.lean-num img") %>% html_attr("alt") 
      #提取课程评分
      course_grade <- web %>% html_nodes("div.course-info-text span.f-l") %>% html_text() %>% str_replace_all(" ","") %>% str_replace_all("\n","") %>% str_replace_all("评分:","")
      course_grade <- course_grade[seq(2,length(course_grade),2)]
      #提取课程价格
      course_price <- web %>% html_nodes("div.course-price") %>% html_text() %>% str_replace_all("¥","")
      #创建数据框存储以上信息
      course <- data.frame(course_names,course_class,course_people,course_grade,course_price)
      course_inf <- rbind(course_inf,course)
    }
    #将数据写入csv文档
    write.csv(course_inf, file="course_inf.csv")
    

    最终爬取结果如下,解螺旋官网上的精品课程共计52门。

    image.png

    下面简单对这部分课程信息做进一步分析,比如想知道这些课程在不同级别上的分布?经分析发现,共计四种课程分级:入门、初级、中级和高级,其中初级类课程最多,高级类课程最少。可见解螺旋的课程设置偏向小白用户,致力于入门和打基础。

    rm(list=ls())
    library("readx")
    course_inf <- read.csv("course_inf.csv", header = T,stringsAsFactors = F)
    
    ##整理数据,修改数据格式
    course_inf$course_people <- as.numeric(as.character(course_inf$course_people))
    course_inf$course_grade <- as.numeric(as.character(course_inf$course_grade))
    course_inf$course_price <- as.numeric(as.character(course_inf$course_price))
    str(course_inf)
    
    #课程在不同级别上的分布
    course_class <- as.data.frame(sort(table(course_inf$course_class),decreasing = T))
    library(ggplot2)
    ggplot(course_class,aes(Var1,Freq)) + geom_bar(stat = "identity") + 
      labs(x = "课程分类", y = "课程数量") +
      theme(panel.background=element_rect(fill='transparent')) + 
      geom_text(mapping = aes(label = Freq),size=4,vjust=-1,color = "black")
    
    image

    往往官网的课程设置也是有讲究的,一般适用群体范围较大的课程会花更多时间和精力去打造,从上述分析中偏基础入门类的课程多达41门,占所有课程的80%。那是不是这部分课程的确受用户偏爱呢?如下图,入门类课程的观看人数多达26000多人,占据份额的一大半。从这些数据不难看出,解螺旋的精品课程中入门类课程设置最多,且也是用户最偏爱的一类课程。

    rumen <- sum(course_inf[course_inf$course_class=="入门","course_people"])
    chuji <- sum(course_inf[course_inf$course_class=="初级","course_people"])
    zhongji <- sum(course_inf[course_inf$course_class=="中级","course_people"])
    gaoji <- sum(course_inf[course_inf$course_class=="高级","course_people"])
    tmp1 <- data.frame("入门"=rumen,"初级"= chuji,"中级" = zhongji, "高级" = gaoji)
    tmp1 <- as.data.frame(t(tmp1))
    tmp1$V2 <- factor(rownames(tmp1),levels = c("入门", "初级" , "中级",   "高级"))
      
    ggplot(tmp1,aes(V2,V1)) + geom_bar(stat = "identity") + 
      labs(x = "课程分类", y = "观看人数") +
      theme(panel.background=element_rect(fill='transparent')) + 
      geom_text(mapping = aes(label = V1),size=4,vjust=-1,color = "black")
    
    image

    以上只是做了些简单分析,有兴趣的小伙伴,可以根据自己需求,个性化的进行分析。此外,若有小伙伴想重复此代码,需要更新自己的cookies,否则容易运行失败。

    往期回顾
    R爬虫在工作中的一点妙用
    R爬虫必备基础——HTML和CSS初识
    R爬虫必备基础——静态网页+动态网页
    R爬虫必备——rvest包的使用
    R爬虫必备基础——CSS+SelectorGadget
    R爬虫必备基础—Chrome开发者工具(F12)
    R爬虫必备基础—HTTP协议
    R爬虫必备—httr+POST请求类爬虫(网易云课堂)
    R爬虫必备基础—rvest为什么不用于动态网页?

    相关文章

      网友评论

          本文标题:R爬虫必备——httr+GET请求类爬虫(解螺旋课程)

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