今天我们来讲一个新专题:爬取“链家网”长沙小区房地产数据,并对长沙房地产信息做数据挖掘与分析。
这个专题标题有点长,暂时就简略为:对长沙房地产数据的挖掘与分析。
这个专题将包含以下几个内容:
如何抓取网页源码
如何解析数据元素
如何使用MongoDB存储数据内容
如何将数据做进一步的分析,得出一些有意思的结论。
今天我们就讲一讲对长沙房地产数据的挖掘与分析【一】,今天的内容不多,主要包含:
安装MongoDB数据库。
预习一下Http协议工作原理及requests,正则表达式re和MongoDB库。
抓取长沙小区2500多个小区的小区名称及对应的小区链接。
一、安装MongoDB和数据库可视化软件
1.1. 安装MongoDB
首先安装MongoDB数据库,我建议安装2.6版本,网上下载mongoDB2.6安装。安装的具体步骤可以参照下面这个视频。
这个视频是以一种批处理的方式启动MongoDB,省去了繁杂的代码启动服务,可以参考一下哦。
1.2. 安装数据库可视化软件。
推荐安装MongoVUE,具体请到官网或其它网站下载。MongoVUE有很多功能,我主要用它来查看数据,并且导出xls数据文件,十分方便。
当然,还可以下载另外一款MongoDB数据库可视化软件:NoSQL Manager for MongoDB,也蛮方便的。
二、熟悉HTTP协议工作原理及requests,正则表达式re和pymongo库
2.1 熟悉HTTP协议工作原理
抓取网页源码很简单,但是在这之前我们应该熟悉一下http的工作原理。
简言之就是三次握手四次挥手,建立TCP需要三次握手才能建立,而断开连接则需要四次握手。
(1)客户端连接到Web服务器
一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。
(2)发送HTTP请求
通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成。
(3)服务器接受请求并返回HTTP响应
Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。
(4)释放连接TCP连接
Web服务器主动关闭TCP套接字,释放TCP连接;客户端被动关闭TCP套接字,释放TCP连接。
(5)客户端浏览器解析HTML内容
客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。
完成(5)后整个html内容就会被客户端浏览器读取,这是B/S架构。当然,还有C/S架构,有兴趣的也可以了解一下。
爬虫就是要模拟浏览器,发消息头,建立TCP连接,所以,整个过程越是将浏览器模拟的真实,服务器端能判断出来是Robot的概率越小,爬取的成功率就越高。
2.2 预习requests库
本次爬虫,我们不打算用urllib,urllib2这两个自带的库,而是采用这个requests这个库爬取。requests是个绝佳的库,安装pip,通过pip install requests安装这个库函数。剩余的网上多查看一下这个库的教程文档。希望大家可以预先了解它,并且能熟练掌握它。
2.3 预习re库
正则表达式re功能强大,执行效率高,具体请参考:
主要用到的:
2.4 预习pymongo库
pymongo是python操作MongoDB数据库的一个非常常用的模块。
一般可以用:
import pymongo
client = MongoClient('localhost','27017')#数据库地址及端口号
dbName = 'lianjia'
#数据库名称
dbTable = 'xiaoqu'
#表的名称
tab = client[dbName][dbTable]
#连接数据库
具体pymongo的介绍可参考:
三、抓取长沙小区2500多个小区的小区名称及对应的小区链接
由于要爬取长沙2500多个小区,其中包括各种信息,包括小区名称,建成时间,物业费,小区经纬度,小区所在市区,楼栋数,总户数等一系列的数据。为防止爬取有误。为保险起见,一般来说,我会分拆为多个小节。比如,我可以先将小区名称以及该小区对应的网址入库。这样,下次我就可以不用从一级网址入口,直接从二级网址,即每个小区链接入口爬取就可以了。这样做的优点时,可随时暂停或终止爬取,不需重复劳动,避免不可控因素。
先上本小节python爬虫代码(采用的是python2.7):
主代码:
# _*_coding:utf-8_*_
import time
import requests
from pub_fuc import re_fuc
from pymongo import MongoClient
import sys
reload(sys)
sys.setdefaultencoding( "utf-8" )
client = MongoClient()
dbName = 'lianjia'
dbTable = 'xiaoqu'
tab = client[dbName][dbTable]
def getresp(req, retries = 2):
try:
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate, sdch',
'Accept-Language': 'zh-CN,zh;q=0.8',
'Cache-Control': 'max-age=0',
'Connection': 'keep-alive',
'Host': 'cs.lianjia.com',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36',
}
ses = requests.session()
ses.get('http://cs.lianjia.com/xiaoqu/rs/')
html = ses.post(req, headers=headers)
data = html.text.encode('iso8859-1').decode('utf-8')
except Exception, what:
print what, req
if retries > 0:
return getresp(req, retries - 1)
else:
print 'GET Failed', req
return ''
return data
main_url = 'http://cs.lianjia.com/xiaoqu/rs/'
cont = getresp(main_url)
rel = [r'<div class="info"><div class="title"><a href="(.*?)" target="_blank" data-bl="list" data-log_index=".*?data-el="xiaoqu">(.*?)</a>']
xiaoqu = re_fuc(cont, rel, 'choice_route')
for x in xiaoqu:
key = {'xiaoqu':x[1], 'url':x[0]}
tab.insert(key)
print '第1页爬取成功!'
for i in xrange(2, 82, 1):
print '开始爬取第%s页'%(str(i))
main_url= 'http://cs.lianjia.com/xiaoqu/pg%s/'%(str(i))
cont = getresp(main_url)
rel = [r'<div class="info"><div class="title"><a href="(.*?)" target="_blank" data-bl="list" data-log_index=".*?data-el="xiaoqu">(.*?)</a>']
xiaoqu = re_fuc(cont, rel, 'choice_route')
for x in xiaoqu:
#print x[0],x[1]
key = {'xiaoqu':x[1], 'url':x[0]}
tab.insert(key)
print '第%s页爬取成功!' % (str(i))
time.sleep(1)
re_fuc.py代码:
#-*-coding:utf8-*-
import re
def re_fuc(cont,rel_list,id_data):
for rel in rel_list:
try:
c = re.compile(rel)
ret = re.findall(c, cont)
if ret:
return ret
else:
pass
except:
pass
return None
本次代码没有什么难度(嘿嘿,我也写不出有难度的代码出来哟~),简单解释一下:
- getresp函数是重试函数,就是一次请求不成功后,再次请求。默认请求次数为2次。
加入了headers,headers是模拟浏览器发消息头,相信预习了http的三次握手过程之后,对这个应该是有了解的。
用了正则表达式。正则表达式需要了解贪婪模式和非贪婪模式。以及. * ?三个字符含义。正则表达式执行效率比较高。对于html的元素提取,我们以后还会讲到lxml。
MongoDB的字典插入。
re_fuc.py代码就是对网页元素的匹配做了一次封装。
爬取完成的TABLE表应该是这样的:
学完本节,你应该掌握:
安装MongoDB数据库。
了解Http协议工作原理及requests,re及pymongo模块。
能自己动手抓取简单的html源码,能够提取出简单的元素并能存储进数据库。
留个问题,如果中途因为某种原因爬虫被迫终止了,是否又要删数据,重新抓取呢?如果不需要,代码上应该怎么自动去重呢?
注:如何实现增量式抓取,如何设计良好的数据库,做到实时更新,快速化判重并减少冗余数据存储是爬虫非常重要的技能。
下一讲讲述:对长沙房地产数据的挖掘与分析【二】。下一节,我们将对这些网址做二次入口爬取。另本专题全部章节将于微信公众号【一只IT汪】首发,欢迎大家的关注,谢谢!
【一只IT汪】公众号刚开通,暂时没有多少内容,但以后会有更多惊喜哟~ 公众号回复您的暂时是微信机器人,别被微信机器人调戏了哈~
本系列教程将不定期更新,敬请关注 :)
如果喜欢,请一定记得点赞哟~ 你的赞就是我更新的动力~ o(*≧▽≦)ツ