声明:用途仅供学习使用
实验一 爬取学堂在线:
一.实验题目
爬取学堂在线的计算机类课程页面内容
点击跳转学堂在线
要求将课程名称、老师、所属学校和选课人数信息,保存到一个csv文件中。
二.实验环境
Pycharm 3.7.0
三.实验分析
(一)思路分析
1.首先,打开学堂在线的网页,选择计算机课程,浏览器选择检查,发现如下显示:
开始以为按照静态页面进行爬取即可,
将spider.py程序如下实现:
import scrapy
from xtest.items import MyItem # 从items.py中引入MyItem对象
class mySpider(scrapy.spiders.Spider):
name = "xtest" # 爬虫的名字是bupt
allowed_domains = ["www.xuetangx.com"] # 允许爬取的网站域名
start_urls = ["https://www.xuetangx.com/search?query=&org=&classify=1&type=&status=&page=1"]
def parse(self, response): # 解析爬取的内容
item = MyItem() # 生成一个在items.py中定义好的Myitem对象,用于接收爬取的数据
for each in response.xpath("/html/body/div/div/div[3]/div[1]/div[1]/div[2]/div[1]"):
item['name'] = each.xpath("div[2]/p[1]/span/text()").extract() # 课程名称
item['teacher'] = each.xpath("div[2]/p[2]/span[1]/span[1]/text()").extract() # 老师昵称
print(item['teacher'])
item['school'] = each.xpath("div[2]/p[2]/span[2]/span/text()").extract() # 开设的学校
item['num'] = each.xpath("div[2]/p[2]/span[3]/text()").extract() # 选课人数
if item['name'] and item['teacher'] and item['school'] and item['num']: # 去掉值为空的数据
yield item # 返回item数据给到pipelines模块
但是最后执行如下结果显示:
爬虫已经关闭,爬取不了任何数据。
2.最后猜想该查询结果页面的是动态页面,进行网页中,点开检查再次观察,发现以下结果:
现在明确确实是动态页面。
3.然后进一步发现是Ajax类型,以下为截图:
点击打开product_lists可以看见课程的相关信息,正是我们需要爬取的内容,如下所示:
4.基于以上的发现明确进行动态页面的爬取。
(二)实现动态页面爬取
1.找到爬取的链接以及请求的方式:
2.构造header,打开检查,找到Headers选项,查看请求头,如下所示:
’
3.将此代码赋值下来,填充headers的构造,代码如下所示:
4.除了请求头此外,还需要post的提交表格数据。
代码部分:
data='{"query":"","chief_org":[],"classify":["1"],"selling_type":[],"status":[],"appid":10000}'
5.在前面第一步已经分析,采取的是post的页面的请求方法,那么借助
FormRequest函数即可实现post请求。
重写start_request(self)函数,然后经过这个函数不断的循环发送请求,该函数代码实现如下:
6.接着就是解析内容的阶段
根据我们的需求,需要爬取课程名称,老师,所属学校以及课程人数,那么将items.py文件如下实现:
那么对于response返回的内容,使用json.loads处理获取到的json文件,json.loads()函数是将json格式数据转换为字典。
网页header部分显示如下:
由上图可知键分别为data与product_list,那么进行product_list内容如下方式进行提取:
7.为了爬取页面按照1-5的顺序,加上以下语句,延迟下载:
那么spider.py文件就如下所示:
8.然后pipelines进行将数据写入csv文件,那么pipelines.py文件如下所示:
9.最后当然需要将管道打开,那么settings.py文件如下所示: