爬虫仅供学习交流使用,请勿用于商业用途,请勿高频爬取数据。由使用爬虫产生的纠纷笔者概不负责。

实验报告原文节选

2.2 遇到障碍:JS动态渲染页面

  • 编写spider.py时遇到了诡异的问题,xpath可以找到符合//*[@id = 'app']的一个标签,但是其是空的,内部没有任何内容。

  • 打印response.text,格式化html,得到的内容如下

    <!DOCTYPE html>
    <html>.....<body ondragstart="return!1"><div id="app"></div><script>var hostName = window.location.hostname,_mtac = {performanceMonitor: 1,senseQuery: 1}; !function() {var e = document.createElement("script");e.src = "//pingjs.qq.com/h5/stats.js?v2.0.4",e.setAttribute("name", "MTAH5"),-1 != hostName.indexOf("jsmh.xuetangx.com") || -1 != hostName.indexOf("www.bnuonline.com") ? e.setAttribute("sid", "500693653") : (e.setAttribute("sid", "500676615"), e.setAttribute("cid", "500679396"));var t = document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e, t)} ()</script><script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js" type="text/javascript"></script><script src="https://static-cdn.xuetangx.com/xtassets/manifest_646ae91479d55300357f.js"></script><script src="https://static-cdn.xuetangx.com/xtassets/0_745d5dea18d788f581ff.js"></script><script src="https://static-cdn.xuetangx.com/xtassets/9_d2c68e421b465c25f7dd.js"></script><script src="https://static-cdn.xuetangx.com/xtassets/119_e4a23c8e374222e46249.js"></script></body></html>
    
    • 页面内并没有任何可以用的信息,信息是在页面加载后,由下面的javascript脚本向服务器获取信息,然后再转化为HTML语句插入到网页中的。而默认的scrapy并不支持运行javascript脚本。
    • 解决方案有两个
      1. scrapy获得javascript脚本执行完后的网页。可以通过配合selenium或者其他工具完成,但是比较麻烦。
      2. 找出javascript脚本使用的数据接口。绕过网页,直接获取数据。

2.3 分析出数据接口

  • 可以去读javascript脚本,但是这样比较费事费力。

  • 我们考虑,页面上的数据每次加载肯定要从服务器动态获取,因为这些内容是要动态刷新的,没人想看到过时的课程数据。但是对于页面上的静态资源,比较图片,则不需要反复加载。通过分析加载页面时动态加载的内容,我们可以找到课程数据的实际来源。而且课程内容这么多,数据量应该不小。

  • 使用Chromium内核的浏览器(或者使用Fiddler抓包),打开该页面,进入开发者控制台,选择Network,刷按F5新,观察元素的加载。加载完毕后,让元素按从大到小排序。如果是之前的访问已经加载过的静态内容, size会显示from memory/disk cache,显示实际大小的就是动态加载内容。选择有实际大小并且最大的内容,一个叫?page=1的项目显得十分可疑,单击打开,发现其是一个json。选择preview选项卡,预览其中的内容,果然是课程信息。

  • 现在尝试在爬虫中重现浏览器的操作。在Headers中找到了Request URL为

    https://www.xuetangx.com/api/v1/lms/get_product_list/?page=1
    

    post的数据(位于最下面的Request Payload)中为

    {"query":"","chief_org":[],"classify":["1"],"selling_type":[],"status":[],"appid":10000}
    

    在爬虫中重现(这里使用requests,也可以用curl或者wget

    import requests as r
    url = 'https://www.xuetangx.com/api/v1/lms/get_product_list/?page=1'
    data = {"query":"","chief_org":[],"classify":["1"],"selling_type":[],"status":[],"appid":10000}
    r0 = r.post(url, data=data)
    print(r0.text)
    

    发现获取的信息是空的

    {"msg": "", "data": {"count": 0, "product_list": []}, "success": true}
    
  • 考虑把Headers也加上。将Requets Headers的内容写成Python字典的形式

    这里推荐使用Convert cURL command syntax to Python requests, Ansible URI, browser fetch, MATLAB, Node.js, R, PHP, Strest, Go, Dart, JSON, Elixir, and Rust code
    在Chromium的Network选项卡左边的Name栏中找到?page=1 项目,右击选择Copy->Copy as cURL(bash),然后粘帖到该网页的curl command栏中,语言选择Python,右边会实时生成一段Python脚本,是用Requests库的复现,直接复制后运行,然后打印response.json(),发现数据被成功获取。

2.4 编写items.py

  •   import scrapyclass XuetangxItem(scrapy.Item):# define the fields for your item here like:name = scrapy.Field()teachers = scrapy.Field()school = scrapy.Field()count = scrapy.Field()
    

2.5 编写spider.py

  • Scrapy下的POST需要使用FormRequest()手动发送请求。默认的Request(包含使用start_urls)都是使用GET方法,本例中的接口只能使用POST方法,使用GET(包括使用浏览器访问接口的URL)会返回一个包含错误消息的json.

  • FormRequest()的参数在scrapy不同版本之间有变化,最新版本中几个常用的参数如下

    • url:必需参数。

      • 需要注意Scrapy并不支持params属性,即参数不能自动填写。接口的地址https://www.xuetangx.com/api/v1/lms/get_product_list/?page={}Requests库中可以写成url = 'https://www.xuetangx.com/api/v1/lms/get_product_list/', params = (('page',page_number),)。在Scrapy中就不可以,需要自己格式化字符串构造地址。(也可以使用urllib
    • headers:指定请求头。本例中需要使用,不然会返回空结果。
    • method: 请求方法,可以是GET或者POST,本例中使用POST.
    • body: 需要POST的表单数据,即Chromium中的Request Payload.
    • callback: 回调函数,指定本请求完成后的item由谁处理。
  • 由于需要手动创造请求,需要重写spiderstart_requests方法,在此处发送所有的请求到引擎。

  • 同时需要注意此时返回的是一个json对象的二进制,需要使用json模块进行相应的模块,比xpath操作HTML更直观。

  •   import scrapyimport jsonfrom pprint import pprintfrom xuetangx.items import XuetangxItemclass XuetangxSpider(scrapy.spiders.Spider):name = "xuetangx"allowed_domains = ["xuetangx.com/"]url_pat = 'https://www.xuetangx.com/api/v1/lms/get_product_list/?page={}'data = '{"query":"","chief_org":[],"classify":["1"],"selling_type":[],"status":[],"appid":10000}'headers = {'django-language': 'zh',# 填写自己的Headers,此处仅做提示用'referer': 'https://www.xuetangx.com/search?query=&org=&classify=1&type=&status=&page=1','authority': 'www.xuetangx.com',}# 不使用start_urls列表,因为要创建POST请求def start_requests(self):for page in range(1,5+1):yield scrapy.FormRequest(url = self.url_pat.format(page),headers = self.headers,method = 'POST',body = self.data,callback= self.parse)def parse(self, response):j = json.loads(response.body)for product in j['data']['product_list']:item = XuetangxItem()item['name'] = product['name']teacher_name_list = []for teacher in product['teacher']:teacher_name_list.append(teacher['name'])item['teachers'] = ','.join(teacher_name_list)item['school'] = product['org']['name']item['count'] = product['count']yield item
    

2.6 编写pipelines.py

  • 本题要求存入csv文件中,需要使用csv模块。

  • 为了避免出现空行(CRLF问题),在打开文件open时需要指定newline=''

  •   import csvclass XuetangxPipeline:def open_spider(self, spider):try:self.file = open('xuetangx.csv','w',newline='')self.csv = csv.writer(self.file)except Exception as err:print(err)def process_item(self, item, spider):self.csv.writerow(list(item.values()))return itemdef close_spider(self, spider):self.file.close()
    

2.7 结果展示

  • 由于我在处理时将多位老师的名字用逗号分隔存储,而csv的分隔符是逗号,所以包含逗号的字符串用引号括了起来。
  • 打开处理管道。很重要,不打开的话,spider.pyparse的结果不会传给pipelines.py,结果只是在终端打印一下而没有持久化。
  •   数据科学导论,"袁博,何隽",清华大学,48659大学计算机基础,卫春芳,湖北大学,46641基于Linux的C++,乔林,清华大学,45886大学计算机基础,"徐红云,刘欣欣,曹晓叶",华南理工大学,45091……
    

[Python程序设计] 用Scrapy爬取学堂在线计算机类课程页面的信息相关推荐

  1. 学堂在线 python_Python作业1:Scrapy爬取学堂在线+链家二手房

    import scrapy import json from pprint import pprint from studyHall.items import StudyhallItem class ...

  2. 七、Python简单爬取学堂在线合作院校页面内容

    这是一个大学生的爬虫作业,我是收钱干活的,比较简单,来过来分享一下. 就是要爬取到合作院校的名称及该所院校在学堂在线开课的数量,将爬取到的数据保存到一个json文件中!例如:"{" ...

  3. scrapy 解析css,Scrapy基础(六)————Scrapy爬取伯乐在线一通过css和xpath解析文章字段...

    上次我们介绍了scrapy的安装和加入debug的main文件,这次重要介绍创建的爬虫的基本爬取有用信息 通过命令(这篇博文)创建了jobbole这个爬虫,并且生成了jobbole.py这个文件,又写 ...

  4. [Python 爬虫] 使用 Scrapy 爬取新浪微博用户信息(四) —— 应对反爬技术(选取 User-Agent、添加 IP代理池以及Cookies池 )

    上一篇:[Python 爬虫] 使用 Scrapy 爬取新浪微博用户信息(三) -- 数据的持久化--使用MongoDB存储爬取的数据 最近项目有些忙,很多需求紧急上线,所以一直没能完善< 使用 ...

  5. [Python 爬虫] 使用 Scrapy 爬取新浪微博用户信息(二) —— 编写一个基本的 Spider 爬取微博用户信息

    上一篇:[Python 爬虫] 使用 Scrapy 爬取新浪微博用户信息(一) -- 新建爬虫项目 在上一篇我们新建了一个 sina_scrapy 的项目,这一节我们开始正式编写爬虫的代码. 选择目标 ...

  6. [Python 爬虫] 使用 Scrapy 爬取新浪微博用户信息(三) —— 数据的持久化——使用MongoDB存储爬取的数据

    上一篇:[Python 爬虫] 使用 Scrapy 爬取新浪微博用户信息(二) -- 编写一个基本的 Spider 爬取微博用户信息 在上一篇博客中,我们已经新建了一个爬虫应用,并简单实现了爬取一位微 ...

  7. Scrapy爬取伯乐在线所有文章

    Scrapy爬取伯乐在线所有文章 1.目标分析 2.Spiders的编写 2.1.网站结构分析 2.2.获取当页文章URL 2.3.获取文章的信息 2.4.文章列表下一页 2.4.编写spiders. ...

  8. Scrapy实例————爬取学堂在线合作院校页面内容

    目标 通过Scrapy爬取到合作院校的名称及该所院校在学堂在线开课的数量,将爬取到的数据保存到一个json文件中,例如:"清华大学,308",地址 http://www.xueta ...

  9. Scrapy爬取伯乐在线的所有文章

    本篇文章将从搭建虚拟环境开始,爬取伯乐在线上的所有文章的数据. 搭建虚拟环境之前需要配置环境变量,该环境变量的变量值为虚拟环境的存放目录 1. 配置环境变量 2.创建虚拟环境 用mkvirtualen ...

  10. scrapy | 爬取伯乐在线全部博文(xpath/css/itemload三种提取方法,同步、异步方式存入MySQL)

    1.目标 伯乐在线网站地址:http://blog.jobbole.com/all-posts/ 爬取伯乐在线的所有文章信息,包括图片网址,标题,发表日期,标签,点赞数,评论数等 将爬取的数据保存至数 ...

最新文章

  1. mysql和oracle执行计划_mysql explain执行计划详解
  2. 新手用python2还是3-新手用python2还是3
  3. 计算字符串相似度算法—Levenshtein
  4. tensorflow: Could not load dynamic library ‘cudart64_101.dll‘ 解决办法
  5. C++中 引用与取地址的区别
  6. C语言有参函数调用时参数间数据传递问题
  7. 须使用visual c 内联汇编语言开发,在VisualC 中使用内联汇编
  8. java this() super()_java中的this和super
  9. 无线文件服务器,文件共享新方法 无线网络文件共享设置
  10. 长沙中职英语计算机等级考试查询,湖南省中等职业教育公共基础课达标训练英语291-300...
  11. QT每日一练day25:触发绘画事件
  12. python制作表格的语句_python根据Excel自动生成创建表sql语句
  13. HTML5新增input表单(HTML5)
  14. 谷歌浏览器下载更新(附带谷歌安装包百度云)
  15. 电动自行车新国标正式发布,推动电池产业转型升级
  16. spark的三种部署模式
  17. 项目管理 : 项目管理技术的七大优势
  18. C语言实验——逆置正整数
  19. win10安装wsl步骤
  20. 情人节的自娱自乐——情书事件

热门文章

  1. teamviewer13试用期已到期,错装商业版怎么还原成个人版?
  2. Linux stress命令详解
  3. apk部分手机安装失败_安装APK文件时提示“解析包出现错误”,看完就知道怎么做了!...
  4. 显微镜下的大明内容_《显微镜下的大明》读后感1000字
  5. Http405错误,方法类型也没有错,解决办法
  6. Pytorch版Lookahead使用及遇到的问题
  7. 自媒体行业的发展和前景
  8. 计算机专业论文要怎么写,计算机专业本科生论文摘要怎么写 计算机专业本科生论文摘要范文参考...
  9. Pr 入门教程如何倾斜移位效果?
  10. redis-trib.rb操作命令