当前位置: 首页 > 编程日记 > 正文

如何高效地爬取链家的房源信息(四)

Python实现的链家网站的爬虫第四部分,最后一部分。


本系列文将以链家南京站为例,使用Python实现链家二手房源信息的爬虫,将数据爬取,并存入数据库中,以便使用。


本系列第一部分为基础:

如何高效地爬取链家的房源信息(一)


本系列第二部分为爬取小区信息:

如何高效地爬取链家的房源信息(二)


本系列第三部分为爬取在售二手房信息:

如何高效地爬取链家的房源信息(三)


本文是第四部分,爬取历史成交二手房信息并存入数据库,部分代码依赖于第一部分,同时依赖于第二部分的结果。


在前文中已经获取了小区信息,并存在了数据库中,直接读库遍历小区进行爬取:

def do_xiaoqu_chengjiao_spider(db_xq,db_cj):

"""

批量爬取小区成交记录

"""

count=0

xq_list=db_xq.fetchall()

for xq in xq_list:

xiaoqu_chengjiao_spider(db_cj,xq[0],xq[1])

count+=1

print ('have spidered %d xiaoqu %s' % (count,xq[0]))

print( 'done')


对某一个小区内的所有成交房源进行爬取,需要分页:

def xiaoqu_chengjiao_spider(db_cj, xq_url=u"https://nj.lianjia.com/xiaoqu/1411000000391/", xq_name=u"default"):

"""

爬取小区成交记录

"""

url = xq_url.replace('xiaoqu/','chengjiao/c');

try:

req = urllib.request.Request(url, headers=hds[random.randint(0, len(hds) - 1)])

source_code = urllib.request.urlopen(req, timeout=10).read()

plain_text = source_code.decode('utf-8');

soup = BeautifulSoup(plain_text,"html.parser")

except (urllib.request.HTTPError, urllib.request.URLError) as e:

print(e)

exception_write('xiaoqu_chengjiao_spider', xq_url)

return

except Exception as e:

print(e)

exception_write('xiaoqu_chengjiao_spider', xq_url)

return

content = soup.find('div', {'class': 'page-box house-lst-page-box'})

total_pages = 0

if content:

d = "d=" + content.get('page-data')

loc = {}

glb = {}

exec(d, glb, loc);

total_pages = loc['d']['totalPage']


print(u"xiaoqu %s chengjiao totalpage %d" % (xq_name,total_pages));

threads = []

for i in range(total_pages):

tmp= u'chengjiao/pg%dc'% (i + 1)

url_page = url.replace('chengjiao/c',tmp);

t = threading.Thread(target=chengjiao_spider, args=(db_cj, url_page))

threads.append(t)

for t in threads:

t.start()

for t in threads:

t.join()


爬取单个页面内的成交记录信息:

def chengjiao_spider(db_cj, url_page=u"https://nj.lianjia.com/chengjiao/pg4c1411000000142/"):

"""

爬取页面链接中的成交记录

"""

print(u"爬取页面%s成交记录" % url_page);

try:

req = urllib.request.Request(url_page, headers=hds[random.randint(0, len(hds) - 1)])

source_code = urllib.request.urlopen(req, timeout=10).read()

plain_text = source_code.decode('utf-8');

soup = BeautifulSoup(plain_text,"html.parser")

except (urllib.request.HTTPError, urllib.request.URLError) as e:

print(e)

exception_write('chengjiao_spider', url_page)

return

except Exception as e:

print(e)

exception_write('chengjiao_spider', url_page)

return


recodenum = 0;

cjs = soup.find('ul', {'class': 'listContent'});

cj_list = cjs.findAll('li', {})

for cj in cj_list:

info_dict = {}

title = cj.find('div', {'class': 'title'});

houseInfo = cj.find('div', {'class': 'houseInfo'});

dealDate = cj.find('div', {'class': 'dealDate'});

totalPrice = cj.find('div', {'class': 'totalPrice'});

positionInfo = cj.find('div', {'class': 'positionInfo'});

source = cj.find('div', {'class': 'source'});

unitPrice = cj.find('div', {'class': 'unitPrice'});

dealHouseInfo = cj.find('div', {'class': 'dealHouseInfo'});

dealCycleeInfo = cj.find('div', {'class': 'dealCycleeInfo'});


href = title.find('a')

if not href:

continue

info_dict.update({u'链接': href.attrs['href']})

content = title.text.split()

if content:

info_dict.update({u'小区名称': content[0]})

info_dict.update({u'户型': content[1]})

info_dict.update({u'面积': content[2]})


content = houseInfo.text.split('|') #unicode(cj.find('div', {'class': 'con'}).renderContents().strip())

if content:

info_dict.update({u'朝向': content[0].strip()})

if len(content) >= 2:

info_dict.update({u'装修': content[1].strip()})

if len(content) >= 3:

info_dict.update({u'电梯': content[2].strip()})


info_dict.update({u'签约时间': dealDate.text})

info_dict.update({u'签约总价': totalPrice.text}) #注意值

content = positionInfo.text.split()

if len(content) >= 2:

info_dict.update({u'楼层': content[0].strip()})

info_dict.update({u'年代楼型': content[1].strip()})

else:

info_dict.update({u'楼层': content[0].strip()})


info_dict.update({u'来源': source.text})

info_dict.update({u'签约单价': unitPrice.text}) #可能为*

#content = dealHouseInfo.text.split()

if dealHouseInfo != None:

for span in dealHouseInfo.find('span', {'class': 'dealHouseTxt'}).findAll('span'):

if span.text.find(u'房屋') != -1:

info_dict.update({u'税费': span.text})  # 满几年

elif span.text.find(u'距') != -1:

info_dict.update({u'地铁': span.text})


#content = dealCycleeInfo.text.split()

if dealCycleeInfo != None:

for span in dealCycleeInfo.find('span',{'class': 'dealCycleTxt'}).findAll('span'):

if span.text.find(u'挂牌') != -1:

info_dict.update({u'挂牌价': span.text})

elif span.text.find(u'成交周期') != -1:

info_dict.update({u'成交周期': span.text})


command = gen_chengjiao_insert_command(info_dict)


db_cj.execute(command, 1)

recodenum += 1;

print(u"爬取页面%s成交记录%d条" % (url_page,recodenum));



爬取的成交记录信息将被存储到数据库表中。




整个爬取过程还是很快的,在爬取完小区、在售、成交三类信息之后,就可以拿这些数据去进行想要做的分析了。


640?wx_fmt=jpeg

长按进行关注。


相关文章:

Quartz2D在项目中的实际使用

还记得大学刚学iOS那会,从学校图书馆借了本iOS开发的书,有一章节介绍了Quartz2D,当时看得一头雾水,感觉这画画线,画画圆有什么用呢🤔️?工作一段时间后,遇到了一些需求,终…

区别:电感、磁珠和零欧电阻的作用

转载:http://www.cntronics.com/sensor-art/80022840 【导读】电感、磁珠和零欧电阻在电路中是常见的身影。对于这三者在电路中的作用及它们之间的区别,相信还有很多工程师不是很清楚。不过没关系,小编在此为大家奉上一篇关于电感、磁珠和零欧…

【转载】Linux下安装、配置、启动Apache

原文地址:http://www.cnblogs.com/zhuque/archive/2012/11/03/2763352.html 安装Apache前准备: 1、检查该环境中是否已经存在httpd服务的配置文件,默认存储路径:/etc/httpd/httpd.conf(这是centos预装的Apache的一个ent版本&#…

MIME格式解析

“ 本文介绍常见的MIME数据格式。”在协议还原中,不可避免地,经常会在各类协议内容中碰到MIME格式,例如标准邮件协议、HTTP协议。那么,什么是MIME呢?MIME是英文Multipurpose Internet Mail Extensions的缩写&#xff0…

AngularJs--过滤器(filter)

过滤器(filter)正如其名,作用就是接收一个输入,通过某个规则进行处理,然后返回处理后的结果。主要用在数据的格式化上,例如获取一个数组中的子集,对数组中的元素进行排序等。ng内置了一些过滤器…

【一步步学小程序】1.创建项目以及TabBar

1.创建项目 如图,创建项目,输入项目名称、选择目录,AppID是唯一标识,我们可以先点如图红框内的测试号,自动生成一个AppID,然后点新建即创建完一个新项目。 2.创建3个页面 确保如图左上角的编译器按钮是…

Yii在window下的安装方法

首先,在http://www.yiichina.com/上下载yii 然后,配置系统环境变量,在win8下,按winx,找到系统->高级系统设置->环境变量->path 把php的运行环境,加入到环境变量中,以分号隔开。如&…

从新手到入门,如何进入协议分析的世界

“ 协议分析与还原自学及入门指南。”有部分朋友给我发消息,说对协议还原很感兴趣,但苦于没人指导,希望得到我的帮助,问我如何进行协议分析的学习。这篇文章从初学者的角度,编列了一个学习指南,希望能对协议…

C# 学习笔记01

想写一个app可以访问数据库,实现对数据库的查询,修改等,突然发现知识实在有限,故选择C#来实现此app。 使用简单的三层架构来作为此app的架构。表现层(UI)、业务逻辑层(BLL)、数据访问…

转载 iOS js oc相互调用(JavaScriptCore) --iOS调用js

iOS js oc相互调用(JavaScriptCore) 从iOS7开始 苹果公布了JavaScriptCore.framework 它使得JS与OC的交互更加方便了。 下面我们就简单了解一下这个框架 首先我导入framework 方法如下 点击Linked Frameworks and Libraries 的添加后 选择 JavaScriptCor…

【一步步学小程序】2.列表展示

我们上一节已经创建了一个可以点击切换的tabbar。这节我们开始正式敲代码,在首页上展示一个可以上下滚动的课程列表: 首先打开上一节的pages/home/homeMain/homeMain.wxml文件,布局相关代码都会在此文件中,小程序的布局方式类似H…

git分支的合并

原文: http://gitbook.liuhui998.com/3_3.html http://gitbook.liuhui998.com/5_3.html 一、如何分支的合并在git中,可以使用git merge 和git rebase两个命令来进行分支的合并。git merge 和git rebase在大体上都差不多,下文主要以git merg…

【一步步学小程序】3. 使用自定义组件(component)

上一节创建了一个包含多个课程数据的列表。这一节我们用自定义组件(component),来优化列表页面,即如图,我们把每个课程单元格封装为组件。 使用组件的好处: 自定义组件可以在不同的页面中重复使用将复杂…

《lua程序设计(第二版)》学习笔记(五)-- 函数基础

-- 第 5 章 函数-- 一种对语句和表达式进行抽象的主要机制 print(os.date()); -- 打印日期 Sun Apr 20 12:44:46 2014 -- 一看到sun,感慨广州没有晴天 -- 函数没有参数也要括号 -- 特殊情况:只有一个参数的时候, 并且参数一个string/table构造…

HTTP协议中的chunked编码解析

“ HTTP协议中的chunked传输编码全接触。”在HTTP协议中,服务器发往客户端的数据中,通常都包括HTTP头和HTTP体,当存在HTTP体的时候,HTTP体的长度通常是由HTTP头内的“Content-Length”字段确定。就像下图:不过&#xf…

html-css实例

<!DOCTYPE html> <html><head><meta charset"utf-8" /><title>求签</title><style type"text/css">*{margin: 0px;padding: 0px;font-family: "微软雅黑",arial,sans-serif;}body{background: url(im…

【Swift】变量/常量/类型总结

1、变量&#xff08;Variable&#xff09; 变量&#xff0c;可以理解为存放某一类型的值的容器&#xff0c;如&#xff1a; var count:Int var shouldRemind:BOOL var text:String var list:[ChecklistItem]一个变量的数据类型&#xff0c;决定了它能存放什么类型的数据。有些…

ODBC更新记录集提示”记录集为只读“

创建的ODBC应用程序默认的记录集不具有只读属性&#xff0c;但是再更新记录表时会提示”记录集为只读“&#xff0c;这是为什么呢&#xff1f; 今天看书找到了答案&#xff1a; 因为MFC中的数据库类不支持需要连接两个或者多个表的记录集更新&#xff0c;如果选择数据源的时候选…

gzip格式分析与识别

“ 介绍gzip格式&#xff0c;识别gzip压缩的数据流量。”在协议分析过程中&#xff0c;经常会发现gzip压缩的数据&#xff0c;例如在HTTP协议中&#xff0c;在HTTP头中会标示&#xff0c;内容编码为gzip、DEFLATE。但是&#xff0c;还有很多情况&#xff0c;例如一些非HTTP协议…

CSS 和 JS 动画哪个更快

基于Javascript的动画暗中同CSS过渡效果一样&#xff0c;甚至更加快&#xff0c;这怎么可能呢&#xff1f;而Adobe和Google持续发布的富媒体移动网站的性能可媲美本地应用&#xff0c;这又怎么可能呢&#xff1f; 本文逐一遍览了基于Javascript的DOM动画库&#xff0c;如Veloci…

C语言之分支结构 if(一)

一 程序的三种基本结构 顺序结构&#xff1a;程序从上往下依次执行&#xff0c;这个叫顺序结构 分支结构&#xff1a;有选择的执行或者不执行某段代码 循环结构&#xff1a;重复的执行某段代码 二 分支结构之if 最简单的俩种用法 (tips: if语句后面的大括号可以省略&#xff1a…

react-native安装Ant Design

1.集成Ant Design到项目 项目根目录中执行命令&#xff1a; npm install ant-design/react-native --save2.集成按需加载babel-plugin-import到项目 项目根目录中执行命令&#xff1a; npm install --save-dev babel-plugin-import3.创建.babelrc文件 根目录中创建新文件…

车联网APP,安全设施薄弱的山寨品

“ 目前的车联网APP&#xff0c;几乎没有安全性可言。”在网络上闲逛&#xff0c;一不小心&#xff0c;逛进了车联网的领地。物联网、车联网、IoT如火如荼&#xff0c;各个大佬、院士加持&#xff0c;看着相当的高大上。但是&#xff0c;在伟岸的外表下&#xff0c;到底真实的情…

CSS里总算是有了一种简单的垂直居中布局的方法了

<!DOCTYPE html> <html xmlns"http://www.w3.org/1999/xhtml"> <head><meta http-equiv"Content-Type" content"text/html; charsetutf-8"/><title>无标题文档</title><style type"text/css"&…

【星榜单】盘点那些坑爹的国产手机们

【星榜单】盘点那些坑爹的国产手机们 国产手机的那些坑爹事儿很多&#xff0c;中庸到基本大众脸的设计还算是有点良心的&#xff0c;那些奇葩的名字、所谓的高配低价低却又山寨级的做工、饥饿营销让你看得到买不到、伪小清新却又华而不实放眼过去的国产智能手机比比皆是&#x…

App Tracking Transparency被拒解决

App Tracking Transparency 如果使用了App Tracking Transparency&#xff0c;苹果要求在iOS 14.5及以上的版本中必须在弹框取得用户同意后&#xff0c;才可以跟踪用户。否则会被拒&#xff1a; 解决方案 参照官方文档说明&#xff08;https://developer.apple.com/documen…

ProtoBuf格式详解

“介绍protobuf编码格式。”protobuf是一种数据交换格式&#xff0c;又称PB编码&#xff0c;由Google开源&#xff0c;类似于Json、XML&#xff0c;但其内部是纯二进制格式&#xff0c;比Json&#xff0c;XML等格式要更精炼&#xff0c;主要用于数据的序列化和反序列化&#xf…

Android studio 第二次作业

作业要求&#xff1a; 作一个显示框里面分成三行 一二行占这个框的1/2 第三行独占1/2 第三行里面分成两列第一列占25%&#xff0c;第二列占75%。 屏幕显示效果 实现步骤&#xff1a; <LinearLayout android:orientation"vertical"注意这里是横向布局 …

Cable master (POJ No.1064)

二分搜索思想&#xff1a;bool C(double x)可以得到长度为x的绳子//#define LOCAL #include<stdio.h> #include<math.h> int const MAX_N10005; int const MAX_M100; double const INF100000000; int N,K; double d[MAX_N],lb,ub; //判断是否满足条件 bool C(doubl…

iOS 11 导致tableview 刷新之后漂移问题

在10 系好好的&#xff0c;在11系统刷新只有就会多一个白块。查询才返现&#xff0c;添加一下代码 完美解决此bugself.mainTableView.estimatedRowHeight 0; self.mainTableView.estimatedSectionHeaderHeight 0; self.mainTableView.estimatedSectionFooterHeight 0;