python爬虫分析报告
在python课上布置的作业,第一次进行爬虫,走了很多弯路,也学习到了很多知识,借此记录。
1. 获取学堂在线合作院校页面
要求:
爬取学堂在线的计算机类课程页面内容。
要求将课程名称、老师、所属学校和选课人数信息,保存到一个csv文件中。
链接:https://www.xuetangx.com/search?query=&org=&classify=1&type=&status=&page=1
1.确定目标
打开页面,通过查看网页源代码并没有相关内容。可以猜测具体数据由前端通过ajax请求后端具体数据。在开发者工具中,捕获了如下的json数据:

可以看到这个就是我们要求的json数据。考虑如何获取json数据并取出来,分析一下浏览器的请求,将cURL命令转换成Python请求如下:
import requests
cookies = {
'provider': 'xuetang',
'django_language': 'zh',
}
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0',
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh',
'Content-Type': 'application/json',
'django-language': 'zh',
'xtbz': 'xt',
'x-client': 'web',
'Origin': 'https://www.xuetangx.com',
'Connection': 'keep-alive',
'Referer': 'https://www.xuetangx.com/search?query=&org=&classify=1&type=&status=&page=1',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
'TE': 'Trailers',
}
params = (
('page', '1'),
)
data = '{query:,chief_org:[],classify:[1],selling_type:[],status:[],appid:10000}'
response = requests.post('https://www.xuetangx.com/api/v1/lms/get_product_list/', headers=headers, params=params, cookies=cookies, data=data)
#NB. Original query string below. It seems impossible to parse and
#reproduce query strings 100% accurately so the one below is given
#in case the reproduced version is not "correct".
# response = requests.post('https://www.xuetangx.com/api/v1/lms/get_product_list/?page=1', headers=headers, cookies=cookies, data=data)
分析请求的网页是https://curl.trillworks.com/,可以在浏览器的开发工具里,选择network选项卡(chrome)或者网络选项卡(Firefox),右键点击某个请求文件,在菜单中选择复制→复制为cURL命令,然后到这个网页中粘贴转换为python的request即可
2.设计爬虫
要选取的数据为课程名称、老师、所属学校和选课人数。设计的items.py如下:
# items.py
import scrapy
class XuetangItem(scrapy.Item):
name = scrapy.Field()
teachers = scrapy.Field()
school = scrapy.Field()
count = scrapy.Field()
pass
接下来是重头戏设计spider.py文件。因为爬取的是json数据而不是html静态页面,需要设计start_requests函数来发送请求。结合之前分析的Python request,具体代码如下:
import scrapy
import json
from xuetang.items import XuetangItem
class mySpider(scrapy.spiders.Spider):
name = "xuetang"
allowed_domains = ["www.xuetangx.com/"]
url = "url_pat = 'https://www.xuetangx.com/api/v1/lms/get_product_list/?page={}'"
data = '{"query":"","chief_org":[],"classify":["1"],"selling_type":[],"status":[],"appid":10000}'
# data由分析中得来
headers = {
'Host': 'www.xuetangx.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0',
'authority': 'www.xuetangx.com',
'Accept': 'application/json,text/plain,*/*',
'Accept-Language': 'zh',
'Accept-Encoding': 'gzip, deflate, br',
'django-language': 'zh',
'xtbz': 'xt',
'content-type': 'application/json',
'x-client': 'web',
'Connection': 'keep-alive',
'Referer': 'https://www.xuetangx.com/university/all',
'Cookie': 'provider=xuetang; django_language=zh',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache'
}
# 直接从浏览器抄过来,防止服务器辨析到不是浏览器而导致失败
def start_requests(self):
for page in range(1, 6):
yield scrapy.FormRequest(
url=self.url.format(page),
headers=self.headers,
method='POST',
# 浏览器的请求是POST,而且响应头中写明只允许POST
body=self.data,
callback=self.parse
)
def parse(self, response):
j = json.loads(response.body)
for each in j['data']['org_list']:
item = XuetangItem()
item['name'] = each['name']
item['school'] = each['org']['name']
item['count'] = each['count']
teacher_list = []
for teacher in each['teacher']:
teacher_list.append(teacher['name'])
# 因为有些课程有多个老师,需要逐个保存,写入一条记录里
item['teacher'] = ','.join(teacher_list)
yield item
然后设计pipelines.py文件,将爬取到的数据保存为csv文件:
import csv
class XuetangPipeline(object):
dict_data = {'data': []}
def open_spider(self, spider):
try:
self.file = open('data.csv', "w", encoding="utf-8", 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 item
def close_spider(self, spider):
self.file.close()
这样就可以就行爬虫了,当然还要在setting.py中设置ITEM_PIPELINES。之后可以命令行启动爬虫,也可以运行执行cmd命令的python文件:
from scrapy import cmdline
cmdline.execute("scrapy crawl xuetang".split())
3.数据展示
保存的csv文件内容如下,正好内容为50条,这里仅展示开头一部分:
C++语言程序设计基础,清华大学,424718,"郑莉,李超,徐明星"
数据结构(上),清华大学,411298,邓俊辉
数据结构(下),清华大学,358804,邓俊辉
……
2. 获取链家二手房信息
要求:
爬取链家官网二手房的数据 https://bj.lianjia.com/ershoufang/
要求爬取北京市东城、西城、海淀和朝阳四个城区的数据(每个区爬取5页),将楼盘名称、总价、平米数、单价保存到json文件中。
1.确定目标
打开网页,查看网页源代码,可以看到在源代码中间已经包含了二手房信息,说明页面由后端渲染完毕后返回到浏览器,这样可以通过Xpath来爬取相关内容。分析一下某个楼盘的信息结构:
<html>
<head></head>
<body>
<a class="noresultRecommend img LOGCLICKDATA" href="https://bj.lianjia.com/ershoufang/101109392759.html" target="_blank" data-log_index="1" data-el="ershoufang" data-housecode="101109392759" data-is_focus="" data-sl="">
<!-- 热推标签、埋点 -->
<img src="https://s1.ljcdn.com/feroot/pc/asset/img/vr/vrgold.png?_v=202011171709034" class="vr_item" /><img class="lj-lazy" src="https://image1.ljcdn.com/110000-inspection/pc1_hAjksKeSW_1.jpg.296x216.jpg" data-original="https://image1.ljcdn.com/110000-inspection/pc1_hAjksKeSW_1.jpg.296x216.jpg" alt="北京西城长椿街" style="display: block;" /></a>
<div class="info clear">
<div class="title">
<a class="" href="https://bj.lianjia.com/ershoufang/101109392759.html" target="_blank" data-log_index="1" data-el="ershoufang" data-housecode="101109392759" data-is_focus="" data-sl="">槐柏树街南里 南北通透两居室 精装修</a>
<!-- 拆分标签 只留一个优先级最高的标签-->
<span class="goodhouse_tag tagBlock">必看好房</span>
</div>
<div class="flood">
<div class="positionInfo">
<span class="positionIcon"></span>
<a href="https://bj.lianjia.com/xiaoqu/1111027374889/" target="_blank" data-log_index="1" data-el="region">槐柏树街南里 </a> -
<a href="https://bj.lianjia.com/ershoufang/changchunjie/" target="_blank">长椿街</a>
</div>
</div>
<div class="address">
<div class="houseInfo">
<span class="houseIcon"></span>2室1厅 | 60.81平米 | 南 北 | 精装 | 中楼层(共6层) | 1991年建 | 板楼
</div>
</div>
<div class="followInfo">
<span class="starIcon"></span>226人关注 / 1个月以前发布
</div>
<div class="tag">
<span class="subway">近地铁</span>
<span class="isVrFutureHome">VR看装修</span>
<span class="five">房本满两年</span>
<span class="haskey">随时看房</span>
</div>
<div class="priceInfo">
<div class="totalPrice">
<span>600</span>万
</div>
<div class="unitPrice" data-hid="101109392759" data-rid="1111027374889" data-price="98668">
<span>单价98668元/平米</span>
</div>
</div>
</div>
<div class="listButtonContainer">
<div class="btn-follow followBtn" data-hid="101109392759">
<span class="follow-text">关注</span>
</div>
<div class="compareBtn LOGCLICK" data-hid="101109392759" log-mod="101109392759" data-log_evtid="10230">
加入对比
</div>
</div>
</body>
</html>
可以看到房子的名称在class="title"的div下的a标签内,平米数保存在class="houseInfo"的div里,但需要截取一下字符串,单价和总价均保存在class="priceInfo"的div中,有趣的是有些信息没有单价显示,即span里的元素为空,但是观察到其父元素div内有一个属性data-price,其值正好等于单价,因此提取这个即可。
2.设计爬虫
需要保存的数据为楼盘名字、平米数、总价、单价。items.py如下:
import scrapy
class YijiaItem(scrapy.Item):
# define the fields for your item here like:
name = scrapy.Field()
square = scrapy.Field()
price = scrapy.Field()
total = scrapy.Field()
pass
分析要爬虫的页面,网页提供了选择区的筛选,点击“西城区”后网页地址变为了https://bj.lianjia.com/ershoufang/xicheng/,因此可以将网页地址的变动部分用format去填充。spider.py的内容如下:
from yijia.items import YijiaItem
import scrapy
class mySpider(scrapy.spiders.Spider):
name = 'lianjia'
allowed_domains = ["bj.lianjia.com/"]
url = "https://bj.lianjia.com/ershoufang/{}/pg{}/"
# 第一个地方为地区,第二个为页数
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
}
#抄来浏览器的header
def start_requests(self):
positions = ["dongceng", "xicheng", "chaoyang", "haidian"]
for position in positions:
for page in range(1, 6):
yield scrapy.FormRequest(
url=self.url.format(position, page),
method="GET",
headers=self.headers,
callback=self.parse
)
def parse(self, response):
for each in response.xpath("/html/body/div[4]/div[1]/ul/li"):
item = YijiaItem()
item['name'] = each.xpath("div[1]/div[1]/a/text()").extract()[0]
house_info = each.xpath("div[1]/div[3]/div[1]/text()").extract()[0].split('|')
item['square'] = house_info[1].strip()
item['total'] = each.xpath("div[1]/div[6]/div[1]/span/text()").extract()[0] + "万元"
item['price'] = each.xpath("div[1]/div[6]/div[2]/@data-price").extract()[0] + "元/平米"
yield item
然后是设计管道文件,将内容保存为一个json文件:
import json
class YijiaPipeline(object):
dict_data = {'data': []}
def open_spider(self, spider):
try:
self.file = open('data.json', "w", encoding="utf-8")
except Exception as err:
print(err)
def process_item(self, item, spider):
dict_item = dict(item)
self.dict_data['data'].append(dict_item)
return item
def close_spider(self, spider):
self.file.write(json.dumps(self.dict_data, ensure_ascii=False, indent=4, separators=(',', ':')))
self.file.close()
最后仿照前一个样例进行爬虫即可。
3.数据展示
保存的json文件内容如下所示,这里只提供前三条供展示:
{
"data":[
{
"name":"此房南北通透格局,采光视野无遮挡,交通便利",
"square":"106.5平米",
"total":"1136万元",
"price":"106667元/平米"
},
{
"name":"新安南里 南北通透 2层本房满五年唯一",
"square":"55.08平米",
"total":"565万元",
"price":"102579元/平米"
}
/*省略之后的N条数据*/
]
}
python爬虫分析报告的更多相关文章
- Python爬虫——Python 岗位分析报告
前两篇我们分别爬取了糗事百科和妹子图网站,学习了 Requests, Beautiful Soup 的基本使用.不过前两篇都是从静态 HTML 页面中来筛选出我们需要的信息.这一篇我们来学习下如何来获 ...
- python爬虫——分析天猫iphonX的销售数据
01.引言 这篇文章是我最近刚做的一个项目,会带领大家使用多种技术实现一个非常有趣的项目,该项目是关于苹果机(iphoneX)的销售数据分析,是网络爬虫和数据分析的综合应用项目.本项目会分别从天猫和京 ...
- 04爬取拉勾网Python岗位分析报告
# 导入需要的包import requestsimport time,randomfrom openpyxl import Workbookimport pymysql.cursors#@ 连接数据库 ...
- Python 爬虫利器 Selenium 介绍
Python 爬虫利器 Selenium 介绍 转 https://mp.weixin.qq.com/s/YJGjZkUejEos_yJ1ukp5kw 前面几节,我们学习了用 requests 构造页 ...
- 学习笔记之Python爬虫
Python 爬虫介绍 | 菜鸟教程 http://www.runoob.com/w3cnote/python-spider-intro.html https://blog.csdn.net/sina ...
- Python爬虫和情感分析简介
摘要 这篇短文的目的是分享我这几天里从头开始学习Python爬虫技术的经验,并展示对爬取的文本进行情感分析(文本分类)的一些挖掘结果. 不同于其他专注爬虫技术的介绍,这里首先阐述爬取网络数据动机,接着 ...
- 推荐一个利用 python 生成 pptx 分析报告的工具包:reportgen
reportgen v0.1.8 更新介绍 这段时间,我对 reportgen 进行了大工程量的修改和更新.将之前在各个文章中出现的函数进行了封装,同时也对现有工具包的一些逻辑进行了调整. 1.rep ...
- python 生成 pptx 分析报告的工具包:reportgen
python机器学习-sklearn挖掘乳腺癌细胞( 博主亲自录制) 网易云观看地址 https://study.163.com/course/introduction.htm?courseId=10 ...
- python爬虫之分析Ajax请求抓取抓取今日头条街拍美图(七)
python爬虫之分析Ajax请求抓取抓取今日头条街拍美图 一.分析网站 1.进入浏览器,搜索今日头条,在搜索栏搜索街拍,然后选择图集这一栏. 2.按F12打开开发者工具,刷新网页,这时网页回弹到综合 ...
随机推荐
- centos8平台用NetworkManager/nmcli管理网络
一,centos8上,网络服务的管理需要NetworkManager服务 1,NetworkManager的服务操作 启动 [root@localhost network-scripts]# syst ...
- 跟我一起学Redis之看完这篇比常人多会三种类型实战(又搞了几个小时)
前言 对于Redis而言,很多小伙伴只关注其关键的五大基础类型:string.hash.list.set.sorted set(有序集合),其实还有三种特殊类型在很多应用场景也比较适合使用,分别是:b ...
- 正则匹配img标签 蜘蛛 爬取分析 新闻采集
string ostr = "aaaaaa<img asddsa src=\"\" asddsasd />aaaaaaa<img src=\" ...
- Storage API简介和存储限制与逐出策略
目录 简介 常用的客户端存储方式 data storage的类型 逐出策略 Storage API estimate persist persisted 综合使用 总结 简介 对于现代浏览器来说,为了 ...
- Markdown--补充版
markdown语法实例 markdown语法实例 强调 分割线 引用 标题Setext方式 大标题 小标题 标题Atx方式 一级标题 二级标题 三级标题 四级标题 五级标题 六级标题 无序列表 有序 ...
- RocketMQ单节点搭建
RocketMQ服务搭建 下载RocketMQ源码: http://mirror.bit.edu.cn/apache/rocketmq/4.4.0/rocketmq-all-4.4.0-source- ...
- PowerShell类grep
PowerShell类grep 方法一: windows下没有grep不过有findstr, 功能差不多 方法二: powershell自带的正择功能 xxx | where {$_ -match & ...
- Java 中的 3 个双引号是什么语法?Java 15 刷新你的认知!
Java 中的 3 个双引号 """ 是什么语法? 这是 Java 15 新出的,刷新你的认知! 一.前言 在 Java 15 的推出的时候,Text Blocks 正式 ...
- CTF-misc:老板,再来几道misc玩玩
[BJDCTF 2nd]最简单的misc-y1ng 得到一个图片,提示格式损坏,修补一下文件头 然后得到一张图片 直接python16进制转字符串 >>> string = &quo ...
- vue组件使用name属性来生成递归组件
先来个简单的数据 1 lists = [{ 2 id: 1, 3 title: '第一层', 4 children: [{ 5 id: 3, 6 title: '第二层', 7 children: [ ...