python 学习 搜房网爬取"/>
python 学习 搜房网爬取
要写扩写一篇关于城市轨道交通和楼盘价格之间关系的论文,所以需要全国楼盘的数据,这些数据决定从搜房网上面爬取,所以就开始着手写代码。
断断续续地摸索了一个星期,终于可以比价粗糙地爬取出搜房网里的楼盘详情数据。由于中国目前只有二十个城市开通了地铁,并不算多,所以在更换搜房网城市页面上打算手动输入城市网址。打开网页的步骤是:打开城市页面---打开每个楼盘的页面---打开楼盘详情页面开始抓取。分别用了三个函数来实现这三个步骤。
大致地阐述一下在编写这个脚本的时候遇到的四个问题:
1、刚开始的时候想直接打开楼盘详情页面,但是在寻找URL的规律的时候发现,楼盘详情的页面URL上有一串特殊的数字,而且基本是随机的,所以无法找到规律,解决方法:从上一级的页面中抓取楼盘详情页面的URL。
2、在打开楼盘页面的时候发现正则匹配不到所要的URL,一开始以为是中文编码又出了问题。寻找了很多方法,都没有解决。后来发现这些乱码有点特殊,有大量的繁体字,后来找到原因,原来是这些页面被压缩了。而且有少部分页面没有被压缩。解决方法:用gzip模块进行解压缩,并用适当的方法判断页面是不是被压缩了,若没有被压缩,就跳过gzip解压缩的步骤。
3、访问超时问题,由于是新手,对于timeout的运用不了解,所以花了不少时间去探索try模块,使得如何在访问超时的时候能不跳出循环,最后得以解决。
4、在抓取之后写入csv文件的时候发现大部分的汉字不能正常显示,出现大量繁体字,只有少数几条显示正常。摸索了很久,发现压缩页面抓取的数据和非压缩页面抓取的数据写入同一个csv的时候,windows就无法正确识别,所以只有非压缩数据才能正常显示。解决方法:两类数据分别写入两个csv,然后手动合并。
接下来就要去用其他软件来测量楼盘和地铁站、主干线等之间的距离了。
最后附上脚本。
#-*- coding:utf-8 -*-#######################
#搜房网楼盘数据爬取# 目前通地铁的城市:
# 北京、天津、香港、上海、广州、深圳、南京、沈阳、成都、重庆、
# 西安、苏州、昆明、杭州、武汉、哈尔滨、郑州、长沙、宁波、无锡。
########################import urllib
import urllib2
import re
import csv
import gzip
from cStringIO import StringIO
import time
import socket# socket.setdefaulttimeout(20)num = 0
def addr_lou(): #这个函数是用于获得一年当中开盘的各个楼盘的urladdr = []global num for x in xrange(201406,201418):if x > 201412:x = x + 88 #以上几步是为了模拟出2014年6月到2015年5月的几个日期数字。for i in xrange(1,30): #模拟翻页try: #这个try是针对下面timeout给出的,这样就不会在打开网页超时的时候跳出循环。下面的try也是一样的道理citypage_url = '{0}_or_pa{1}.htm'.format(x,i) response = urllib2.urlopen(citypage_url,timeout =20) #设置20秒超时result = response.read()p = repile(r'''<li class="d1"><strong class="f14 fb_blue"><a href="(.+?)" target="_blank" title="(.+?)">''') #用正则匹配网址,抠出来match1 = p.findall(result)print match1print len(match1)num = num + len(match1)if len(match1) == 0:print numbreak #当某页没有楼盘的时候跳出循环else:for url_loupan in xrange(len(match1)):addr.append(str(match1[url_loupan][0]))except socket.timeout, e:print 'state 1 time out!'return addr #返回地址列表addr1 = addr_lou()def detail_page(): #这个函数用于打开每个楼盘页面,在每个楼盘页面找到“楼盘详情”这个子网页的urldetail_addr = []global num1num1 = 0 for page in addr1:try:respon = urllib2.urlopen(page,timeout = 20) #20秒超时resu = respon.read()resu = gzip.GzipFile(fileobj=StringIO(resu), mode="r") #在抓取网页的时候发现,搜房网的大多数页面的源代码都是压缩的,所以要有个解压步骤才能与正则匹配resu = resu.read().decode('gbk').encode('utf-8')p1 = repile(r'''<a href="(.+?)" id="xfxq_C02_07" target="_self">.+?</a>''') #正则匹配URLmatch2 = p1.findall(resu)for i in match2:print inum1 = num1 + 1print num1, numdetail_addr.append(i)time.sleep(2)except urllib2.URLError,msg:passexcept socket.timeout, e:print 'state 2 time out!'return detail_addrlistdetail = detail_page()#listdetail =['.htm','.htm',
# '.htm']def get_detail(): #这个函数是用于打开每个“楼盘详情”页,在上面抓取所需要的信息,写入csv文档global num2num2 = 0xieru = []xieruya = []# 实践中发现,搜房网的大部分页面是加压缩的,而少数没有压缩,但是如果将压缩和非压缩的文字抓取出来以后写入同一个csv文件会出现Windows无法识别的情况#所以创建两个不同的csv文件,分别写入。csvfile = open('C:/Python27/datadata/beijing.csv', 'ab+')csvfileya = open('C:/Python27/datadata/beijingya.csv', 'ab+')for detail_of_house in listdetail:try:res = urllib2.urlopen(detail_of_house, timeout = 20)pipei_1 = repile(r'<h1><a class="ts_linear" id="" href=".+?" title=".+?" target=".+?">(.+?)</a></h1>') #抓取楼盘名称pipei_2 = repile(r'</strong>([\s\S]+?)</td>') #抓取详情,这是一个很宽泛的正则式子,能抓取所有的详情,但不精细neirong = res.read()zipwhether = re.search(pipei_1,neirong) #判断是否为压缩的页面if zipwhether: #不是压缩页面xijie_1 = pipei_1.findall(neirong)xijie_2 = pipei_2.findall(neirong)xijie = xijie_1 + xijie_2xijie = tuple(xijie)xieru.append(xijie)print '111'else: #是压缩页面neirong = gzip.GzipFile(fileobj=StringIO(neirong), mode="r")neirong = neirong.read().decode('gbk').encode('utf-8') #解压缩xijie_1 = pipei_1.findall(neirong)xijie_2 = pipei_2.findall(neirong)xijie = xijie_1 + xijie_2xijie = tuple(xijie)xieruya.append(xijie)print '222'num2 = num2 + 1print xijieprint num2, num1, numtime.sleep(3)except socket.timeout, e:print 'state 3 time out!'print xieruprint xieruyawriter = csv.writer(csvfile, dialect='excel')writerya = csv.writer(csvfileya, dialect='excel') #写入两个csv文档writer.writerows(xieru)writerya.writerows(xieruya)csvfile.close()csvfileya.close()get_detail()
转载于:
更多推荐
python 学习 搜房网爬取
发布评论