python爬取电脑本地数据,python爬取自如数据

本文介绍了使用Python进行网络爬虫实战,目标是抓取自如网北京地区的房源信息。通过分析页面结构和动态加载的数据,解析价格、面积等关键字段,并针对动态背景图的价格展示方式,提取数字。最后,讨论了如何存储数据到MySQL数据库,并给出了数据表结构。整个过程涉及到requests、BeautifulSoup和正则表达式等技术,同时也涉及到了JavaScript动态生成的图片解析问题。
摘要由CSDN通过智能技术生成

前言

学习python有一小段时间了,爬虫也看了一些,所以想拿个简单点的练一下手,而且最近碰上自如比较火,这里就用自如来练手把

分析

006tNbRwgy1fvb8ggh58ej31660wmgzg.jpg

上面那个是自如北京的搜索页面,按照我的理解,所有的房源和一些基本信息应该都可以从这个页面得来(自如宅是自如自己的广告,不是我们需要的),这些都是页面看到的信息,还有一个信息我们其实也可以拿下来,用于以后如果有需要的时候用,就是每一个房源的详细页面链接

006tNbRwgy1fvb8ko9f2zj319i0awqa5.jpg

然后我们看到其实链接都是固定套路,不一样的只是后面那串数子,我猜就是数据库保存的主键了,那么我们也就可以开始准备我们自己的数据格式了(我这里是保存在mysql的)

CREATE TABLE `beijing` (

`id` int(10) NOT NULL AUTO_INCREMENT COMMENT '主键id',

`price` int(10) NOT NULL DEFAULT '0' COMMENT '价格',

`size` decimal(10,2) DEFAULT '0.00' COMMENT '大小',

`floor` int(10) NOT NULL DEFAULT '0' COMMENT '楼层',

`total_floor` int(10) NOT NULL DEFAULT '0' COMMENT '总楼层',

`room` int(10) NOT NULL DEFAULT '0' COMMENT '房',

`hall` int(10) NOT NULL DEFAULT '0' COMMENT '厅',

`line` varchar(20) NOT NULL DEFAULT '' COMMENT '几号线',

`station` varchar(20) NOT NULL DEFAULT '' COMMENT '地铁站',

`distance` int(10) NOT NULL DEFAULT '0' COMMENT '距离',

`taps` varchar(200) NOT NULL DEFAULT '' COMMENT '标签',

`href` varchar(100) NOT NULL DEFAULT '' COMMENT '链接',

`address` varchar(100) NOT NULL DEFAULT '' COMMENT '附近地址',

`area` varchar(20) NOT NULL DEFAULT '' COMMENT '区',

`phase` varchar(20) NOT NULL DEFAULT '' COMMENT '收费周期',

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

接下来我们就开始分析页面,首先我发现,点击分页2的时候,url改变了

http://www.ziroom.com/z/nl/z3.html?p=2 很简单,只是一个普通的p来控制,但是这个会有一个问题,就是我们看全部的这个页的时候,发现只有50页,后面的数据就出不来了,北京的房源实际是不止那么少的,我就去点了另外一个链接

006tNbRwly1fvb8u804uej30kz08r75v.jpg

出现了只有13页,是不是说,每个标签的全部下面都不会超过50的分页,我们只需要去拿这些链接下面的数据就可以了呢,然后我就点了朝阳区下面的全部的这个链接,发现页数也是50,也就是说,我们不能拿这个标签,还需要再细一级,拿每一个区域下面的每一个标签(不拿全部的这个标签,因为数据这样就重复了),拿这些标签是在zindex6下面的ul下的每一个li的第三个span开始一直到最后的一个span里面的a变迁的href的属性

006tNbRwgy1fvb931oldcj30lq0a2mz1.jpg

r = requests.get(self.url)

bsObj = BeautifulSoup(r.text, 'lxml')

lis = bsObj.select('.zIndex6 ul li')

for li in lis[1:]:

hs = li.select('span')[2:]

for h in hs:

# 这个就是了

href = 'http:' + h.select('a')[0].attrs.get('href')

这里,我们拿到了每一个页面,我们还需要知道这个页面有多少分页,好方便我们去循环

bsObj = self.get_html(url)

page_str = bsObj.find(string=re.compile('共([0-9]*)页'))

page = re.search('共([0-9]*)页', page_str).group(1)

接下来我们是不是就可以开始抓取了呢,不是的,其实还有一个问题,我们看价格

006tNbRwgy1fvb977yfgaj311p0eeafw.jpg

它的价格既不是文本,也不是图片,而是用css来控制的,怎么控制

006tNbRwgy1fvb989e0mpj31330gsdmg.jpg

我们找到这个css后面的背景图,发现是一个类似雪碧图的东西

006tNbRwgy1fvb99a6j29j309c01pjra.jpg

而刚刚那个价格是怎么来的,2130,

2对应的位移是270,在雪碧图的最第十个(index=9),1对应的位移是30,在雪碧图的第二个(index=1),3对应的位置是60,在雪碧图的第三个

我们已经找到规律了

i = re.search('background-position:-([0-9]*)px', style).group(1)

k = int(int(i) / 30)

// code为雪碧图的数字

price_str += code[k:k + 1]

那么是不是我们这个图的数字排序是固定的,我们打开另外一个链接,发现不是的,这个图片是随机生成的,也就是说,我们没打开一个链接,都是不一样的,那么要怎么找到这个图片呢,看源码,我们发现这么一个js

var offset_unit = 30;

if(window.devicePixelRatio >1){

$('body').addClass('ratio2');

}

var ROOM_PRICE = {"image":"//static8.ziroom.com/phoenix/pc/images/price/b7944d44332aca7b65a0df428ec83cads.png","offset":[[9,1,2,6],[9,5,4,6],[1,7,4,6],[1,7,4,6],[9,2,4,6],[9,9,4,6],[9,9,4,6],[1,7,8,6],[9,1,2,6],[9,7,8,6],[5,6,8,6],[8,6,8,6],[9,3,2,6],[9,8,2,6],[9,5,2,6],[9,8,8,6],[8,6,4,6],[9,6,4,6]]};

$('#houseList p.price').each(function(i){

var dom = $(this);

if(!ROOM_PRICE['offset'] || !ROOM_PRICE['offset'][i]) return ;

var pos = ROOM_PRICE['offset'][i];

for(i in pos){

var inx = pos.length -i -1;

var seg = $('', {'style':'background-position:-'+(pos[inx]*offset_unit)+'px', 'class':'num'});

dom.prepend(seg);

}

var seg = $('', {'style':'background-position:1000px', 'class':'num rmb'}).html('¥');

dom.prepend(seg);

});

这个图片的链接就在这里,我们需要提取出来

js_str = bsObj.find(string=re.compile("//static8.ziroom.com/phoenix/pc/images/price/(.*).png"))

img_url = 'http:' + re.search('//static8.ziroom.com/phoenix/pc/images/price/(.*).png', js_str).group(0)

拿出来以后,我们还需要借助一个工具来识别出来这个数字是怎样的,下载下来放在一个地方,这样我们就得到了这个数字了,

path = './code.png'

urllib.request.urlretrieve(img_url, path)

image = Image.open(path)

code = pytesseract.image_to_string(image, config='--psm 6')

这样,我们就可以按照这个逻辑来一步一步的完成这个爬取,最后源码放在了GitHub,需要的自取合适的城市

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值