学习记录:搜房网新楼盘信息爬虫

目标:爬取海南搜房网上的海南新楼盘信息

一、搜集待爬取的目标网址

先打开海南搜房网进入新楼盘页面进行研究,
http://newhouse.hn.fang.com/
但是这个页面主要是信息聚合呈现,新楼盘信息并不全,接着找到列表页,
http://newhouse.hn.fang.com/house/s/
这回是想要的了。
经研究发现该列表页的网址加上分页为如下形式,分页共有28页,分页字段主要是在/b91/这部分
从b91到b928,这样如果把这28页爬完就能初步得到全部新楼盘条目,接着再对每个新楼盘的主页进行爬取提取信息,就能得到想要的内容。
http://newhouse.hn.fang.com/house/s/b91/?ctm=1.hn.xf_search.page.1
具体某个楼盘主页为:
http://zhongyangwenhuachengld.fang.com
楼盘详情页为:
http://zhongyangwenhuachengld.fang.com/house/5011126788/housedetail.htm
开始写代码,先导入依赖的库

import requests
import re
from bs4 import BeautifulSoup

写了一个函数用于提取某个页面中包含的所有不重复链接,返回一个列表

def get_page_urls(url,regular="\w+"):
    if url is None:
        return None
    new_urls = set()
    headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/5.0.2.2000 Chrome/47.0.2526.73 Safari/537.36' }
    r = requests.get(url,headers=headers,timeout=None)
    if r.status_code == 200:
        soup = BeautifulSoup(r.text, 'html.parser',from_encoding='utf-8')
        links = soup.find_all('a', href=re.compile(r'%s' % regular))
        for link in links:
            new_url = link['href']
            new_urls.add(new_url)
            return list(new_urls)

没想到在去重这部分花了很多时间。
开始对于每一个列表页面进行下载和解析,解析页面内所有的<a>标签,将链接地址提取出来,这里使用的正则表达式如下:

^https?://\w+.fang.com/$

将提取到的网址列表先存入一个set(),保证在一个页面上抓到的网址没有重复,抓取完后再将该集合转成list存入一个整体的网址列表中。
然后对全部网址进行去除重复,这里要去掉的重复网址是指页面上其他的非楼盘链接,由于每一个楼盘列表页都会有这些重复的信息,一共抓了28页说明会有28个重复,因此要想办法去除这一部分的链接。
想来想去,想出先找出重复的网址,保存进一个列表中,然后再将全部网址列表跟重复网址列表进行比较,若有相同项则从全部网址列表中删除重复网址项,这样就能得出最后想要的每个新楼盘主页。重点代码为:

if all_urls.count(housepage) > 1:

总觉得这样做是个笨办法效率不高,因为有重复操作,不知道有没有更方便的算法,目前想不出来。
经过一番提取去重后,得到一个所有楼盘详情页链接的文本文件,用于后续信息抓取。保存的代码为:

with open('soufangwang-detail.txt','w',encoding='utf-8') as f:
    for i in all_detail_urls:
        f.write(i)
        f.write("\n")

二、抓取信息

首先研究了一下楼盘详情页结构,想爬取的结构信息是如下这样的,每条信息在一条li的下面有两个<div>,第一个是信息名称,第二个是信息值,90%的信息都是这样的结构,除了部分标题,主图等:

<li>
<div class="list-left">交房时间:</div>
<div class="list-right">预计2017年6月30日A#、B#、C#交房</div>
</li>

开始的想法是针对信息条目,一条条分析进行抓取,根据每个想要的信息构造对应的抓取函数:

name_node = soup.find('h1').find('a',class_="ts_linear")
data["楼盘名称"] = name_node.get_text()
address_node = soup.find('div',string = re.compile("楼盘地址")).find_next('div')
data["楼盘地址"] = address_node.get_text()

但是这样做,首先是发现如果有的信息名称是三个字的话,搜房网会在中间插入i标签,像下面的例子,导致抓取函数无法抓取到正确的<div>。

<li>
<div class="list-left">容<i style="margin-right: 6px;"></i>积<i style="margin-right: 6px;"></i>率:</div>
<div class="list-right">3.50 </div>
</li>

于是在这里研究了好久,先是各种换搜索正则表达式,怎么都搜不到,后来突发奇想,能不能在抓取之前把所有的i标签去掉,于是查文档,写了如下代码

soup = BeautifulSoup(r.text, 'html.parser')
    for tag_i in soup.findAll('i'):
    tag_i.decompose()

这样先对下载到的文档进行处理再抓取应该是可以的,但是很奇怪,去掉i标签后文字还是无法查找到,这回真的卡壳了。
然后经过一番冥思苦想,忽然想到,干嘛要一个个信息来针对性抓取啊,既然它结构大部分都是相同的,干脆全部抓取出来存入一个字典里好了。于是开始写代码:

data = {}
key_nodes = soup.findAll('div', class_="list-left")
for key_node in key_nodes:
    key = key_node.get_text().replace("\t","").replace("\n","").replace("\r","").replace(":","").strip()
    value_node = key_node.find_next('div')
    value = value_node.get_text().replace("\t","").replace("\n","").replace("\r","").strip()
    data[key] = value

抓取成功!发现这样做不光效率高,而且既方便又能容错,获得的信息也全,唉怎么不早点想到呢,折腾好久。
另外在页面结构中发现有一个<script>标签内有楼盘的主图,因此也想把这部分抓取下来,这段的原始结构是这样的:

<script>
newcode='5011111904';
projn = '清澜半岛';
newhousedomaintail='house/';
newhousedomain = 'http://newhouse.hn.fang.com';
address='文昌市';
vcity= '海南';
ucity = '%BA%A3%C4%CF';
price = '13000';
pricetype = '元/平方米';
priceright = '13000';
pricetyperight = '元/平方米';
face = 'http://imgs.soufun.com/house/2013_10/30/hainan/1383115329744_000.jpg';
houseurl = 'http://qinglanbandao.fang.com/';
microID=0;
bbsError ="0";
bbs_id ="5011111904";
</script>

先初步写了个节点抓取语句,成功找到该<script>标签

script_node = soup.find('script', string = re.compile("face ="))

但是抓取之后怎么转成字典的键值对呢,搜索加研究,使用split()函数可以实现,方法如下,注意处理末尾多出来的一个分号:

subdata = (script_node.get_text().replace("\r","").replace("\n","").replace("\t","").replace(";", ",").replace("'","").replace(" ",""))[:-1]
subdata_dict = dict(s.split('=') for s in subdata.split(','))
data['楼盘主图'] = subdata_dict['face']
data['楼盘主页'] = subdata_dict['houseurl']

一些小问题和解决方法:

  • 页面中文乱码,若是知道页面编码的话,可以直接写
r.encoding = "所用编码"

如果不知道的话,可以试试写上,一般都会解决

r.encoding = r.apparent_encoding

但是有些页面怎么弄都是乱码,不知道是不是繁体中文编的码,待解决

  • 删除文档中的换行符回车符制表符和空格,一般用
replace("\n","") #删除全部换行符
strip() #删除开头和结尾的空白符(包括'\n', '\r', '\t',  ' ')
rstrip('\n') #删除结尾的换行符
lstrip() #删除开头的空白符

三、存入excel文件

信息抓取到了,要保存为excel文件。
在官网搜索了一下,先在命令行用pip命令下载excel的支持库

pip install xlwt

参考官网的例子,xlw的使用方法为:

wb = xlwt.Workbook() #新建一个工作簿
ws = wb.add_sheet('新工作表') #新建一个工作表
ws.write(行索引, 列索引, 数据) #写入数据
wb.save('海南新楼盘.xls') #保存

这样就成功将海南搜房网新楼盘信息抓取下来了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,932评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,644评论 18 139
  • 这个系列的第六个主题,主要谈一些搜索引擎相关的常见技术。 1995年是搜索引擎商业公司发展的重要起点,《浅谈推荐系...
    我偏笑_NSNirvana阅读 6,610评论 3 24
  • 微信对话框一直显示对方正在输入,许久之后才收到君君给我发过来的消息,我以为会是很长的一段话,结果却是这么简单的一句...
    南遥思故阅读 2,067评论 2 18
  • 《我可以任你宰割》 文/愚木 你打扰了我 等于是杀了我 是否要我反绑双手任你宰割 这就是你的美 惊起了早晨的风 而...
    愚木的简书阅读 450评论 1 1