第二周/第一节练习项目: 在 MongoDB 中筛选房源

1.

标题 说明
网址 http://sh.xiaozhu.com/search-duanzufang-p1-0/
要求1 爬取前3页的数据并存储到mongodb中
要求2 从mogodb中筛选房价大于500元的房源并打印出来
Paste_Image.png
Paste_Image.png

2. 分析

  • 需要导入连接mongodb的库
  • 页面随着p后面的数字变化而变化
  • 每个列表页中有24条房源链接
  • 详情页中的房东性别根据member_girl_ico, member_boy_ico来判断

3. 实现

# vim spider_xiaozhu.py

代码

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
                                                                                                                             
__author__ = 'jhw'


# 导入连接mongodb的库
from pymongo import MongoClient
from bs4 import BeautifulSoup
import requests


# 连接mongodb
client = MongoClient('10.66.17.17', 27017)
# 选择数据库
database = client['xiaozhu']
# 选择collection
item_info = database['item_info_sh']

headers = { 
    'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36'
}


# 定义获取房屋链接的函数
def get_url_from():

    url_list = []
    urls = ['http://sh.xiaozhu.com/search-duanzufang-p{}-0/'.format(i) for i in range(1, 14)]

    for url in urls:
        data = requests.get(url, headers=headers)
        soup = BeautifulSoup(data.text, 'lxml')
        links = soup.select('.result_btm_con.lodgeunitname')

        for link in links:
            url_list.append(link.get('detailurl'))
            print(link.get('detailurl'))

    return url_list


# 定义获取房屋信息的函数
def get_item_from(url):

    data = requests.get(url, headers=headers)
    soup = BeautifulSoup(data.text, 'lxml')
    # 房屋标题
    house_titles = soup.select('.pho_info > h4 > em')
    # 房屋地址
    house_addrs = soup.select('.pr5')
    # 房屋评分
    house_scores = soup.select('em.score-rate')
    # 房屋价格
    house_prices = soup.select('.day_l > span')
    # 房屋第一张图片, 有链接但直接打开报错
    house_pics = soup.select('.pho_show_big > div > img')
    # 房东图片, 有链接但直接打开报错
    landlord_imgs = soup.select('.member_pic > a > img')
    # 房东姓名
    landlord_names = soup.select('div.w_240 > h6 > a')
    # 房东芝麻信用
    landlord_zms = soup.select('.zm_ico.zm_credit')
    # 判断房东性别
    if soup.select('.member_girl_ico'):
        landlord_gens = 'MM'
    elif soup.select('.member_boy_ico'):
        landlord_gens = 'FM'
    else:
        landlord_gens = 'FF'

    data = {
        'title': house_titles[0].get_text() if house_titles else None,
        'house_addr': house_addrs[0].get_text().strip() if house_addrs else None,
        'house_score': house_scores[0].get_text() if house_scores else None,
        'house_price': int(house_prices[0].get_text()) if house_pics else None,
        'house_pic': house_pics[0].get('src') if house_pics else None,
        'landlord_img': landlord_imgs[0].get('src') if landlord_imgs else None,
        'landlord_gen': landlord_gens,
        'landlord_name': landlord_names[0].get_text() if landlord_names else None,
        'landlord_zm': landlord_zms[0].get_text() if landlord_zms else None,
        'url': url,
    }
    # 将数据存储至mongodb
    item_info.insert_one(data)
    print(data)

# 将房屋链接存储至列表
url_list = get_url_from()

# 从列表中取出链接传入get_item_from函数以获取房屋信息
for url in url_list:
    get_item_from(url)

# 从mongodb中筛选出价格大于500元的房屋
for house in item_info.find({'house_price': {'$gt': 500}}):
    print(house)
# python3 spider_xiaozhu.py  // 运行结果

结果

http://sh.xiaozhu.com/fangzi/1174953165.html
http://sh.xiaozhu.com/fangzi/1677560635.html
.
.
.
http://sh.xiaozhu.com/fangzi/2514835762.html
http://sh.xiaozhu.com/fangzi/3424890030.html
http://sh.xiaozhu.com/fangzi/3092487529.html
.
.
.
{'landlord_zm': '671', 'house_price': 466, 'title': '迪士尼|新国际博览中心|地铁零距离|舒适三房', 'house_addr': '上海市浦东区环桥路1137弄', 'url': 'http://sh.xiaozhu.com/fangzi/3266673930.html', 'landlord_gen': 'FM', 'landlord_img': 'http://image.xiaozhustatic1.com/21/4,0,68,7037,374,374,1d69c0b2.jpg', 'house_score': '5分', '_id': ObjectId('577ba20b3dd54e6a47569fec'), 'landlord_name': '水中花7089', 'house_pic': 'http://image.xiaozhustatic1.com/00,800,533/6,0,50,4614,1798,1200,021d8c01.jpg'}
{'landlord_zm': '731', 'house_price': 198, 'title': '打浦桥#日月光#田子坊#瑞金南路独卫主卧', 'house_addr': '上海市徐汇区瑞金南路546号海晖公寓', 'url': 'http://sh.xiaozhu.com/fangzi/2792949163.html', 'landlord_gen': 'MM', 'landlord_img': 'http://image.xiaozhustatic1.com/21/2,0,12,1234,382,382,edf77c10.jpg', 'house_score': '5分', '_id': ObjectId('577ba20c3dd54e6a47569fed'), 'landlord_name': '戒不掉的奶茶', 'house_pic': 'http://image.xiaozhustatic1.com/00,800,533/6,0,64,797,1798,1200,d21c9325.jpg'}
.
.
.
{'landlord_zm': '737', 'house_price': 730, 'title': '外滩,豫园,新天地,旅游温馨便利两居室', 'house_addr': '上海市黄浦区中华路868弄', 'url': 'http://sh.xiaozhu.com/fangzi/1882270235.html', 'landlord_gen': 'FM', 'landlord_img': 'http://image.xiaozhustatic1.com/21/2,0,9,2490,375,375,98d3731a.jpg', 'house_score': '5分', '_id': ObjectId('577ba20c3dd54e6a47569fee'), 'landlord_name': 'linzhijing', 'house_pic': 'http://image.xiaozhustatic1.com/00,800,533/4,0,65,6603,1800,1202,7bb65f83.jpg'}
.
.
.
{'house_price': 566, 'title': '迪士尼|新国展|中式温馨三房', 'landlord_gen': 'FM', 'house_addr': '上海市浦东区秀沿路2585弄', 'landlord_name': '水中花7089', 'landlord_zm': '671', 'landlord_img': 'http://image.xiaozhustatic1.com/21/4,0,68,7037,374,374,1d69c0b2.jpg', 'house_pic': 'http://image.xiaozhustatic1.com/00,800,533/6,0,22,5143,1798,1200,706a8741.jpg', 'url': 'http://sh.xiaozhu.com/fangzi/3267192930.html', '_id': ObjectId('577b83833dd54e5ba1aa663a'), 'house_score': '5分'}
{'house_price': 650, 'title': '法租界 衡山路【复古法式老洋房】带花园', 'landlord_gen': 'MM', 'house_addr': '上海市徐汇区永嘉新村', 'landlord_name': 'CarolineCheung', 'landlord_zm': '724', 'landlord_img': 'http://image.xiaozhustatic1.com/21/3,0,31,877,375,375,e1511563.jpg', 'house_pic': 'http://image.xiaozhustatic1.com/00,800,533/6,0,70,2817,1800,1200,a2d1b86f.jpg', 'url': 'http://sh.xiaozhu.com/fangzi/1265282535.html', '_id': ObjectId('577b83843dd54e5ba0aa663b'), 'house_score': None}
{'house_price': 1680, 'title': '豪华联排别墅虹桥火车站虹桥机场国家会展中心', 'landlord_gen': 'MM', 'house_addr': '上海市青浦区徐泾明珠路555弄(国家会展中心西4公...', 'landlord_name': 'jenny0103', 'landlord_zm': '751', 'landlord_img': 'http://image.xiaozhustatic1.com/21/2,0,73,2626,375,375,ef9e175b.jpg', 'house_pic': 'http://image.xiaozhustatic1.com/00,800,533/3,0,17,5911,1798,1200,d8d5b9d0.jpg', 'url': 'http://sh.xiaozhu.com/fangzi/1682762135.html', '_id': ObjectId('577b83863dd54e5ba0aa663f'), 'house_score': None}
{'house_price': 730, 'title': '外滩,豫园,新天地,旅游温馨便利两居室', 'landlord_gen': 'FM', 'house_addr': '上海市黄浦区中华路868弄', 'landlord_name': 'linzhijing', 'landlord_zm': '737', 'landlord_img': 'http://image.xiaozhustatic1.com/21/2,0,9,2490,375,375,98d3731a.jpg', 'house_pic': 'http://image.xiaozhustatic1.com/00,800,533/4,0,65,6603,1800,1202,7bb65f83.jpg', 'url': 'http://sh.xiaozhu.com/fangzi/1882270235.html', '_id': ObjectId('577ba20c3dd54e6a47569fee'), 'house_score': '5分'}
.
.
.
{'house_price': 558, 'title': '居有故事老洋房,逛法租界巨富长 ', 'landlord_gen': 'MM', 'house_addr': '上海市徐汇区长乐路', 'landlord_name': '上海乔安娜', 'landlord_zm': '788', 'landlord_img': 'http://image.xiaozhustatic1.com/21/6,0,97,1310,488,488,b24e1e39.jpg', 'house_pic': 'http://image.xiaozhustatic1.com/00,800,533/6,0,22,2044,1800,1200,a83dd3ef.jpg', 'url': 'http://sh.xiaozhu.com/fangzi/2980986063.html', '_id': ObjectId('577ba20d3dd54e6a47569fef'), 'house_score': '5分'}

4. 总结

  • python借助于pymongo连接mongodb, 连接时指定IP地址和端口

  • mongodb中的表用collection表示

  • mongodb常用的命令:

    • find: 查询文档
    • database.collection.find()

    查找某collection中的所有数据

    • database.collection.find({}, {'_id': 1, 'field': 1})

    只显示所有数据中的field字段

    • 条件操作符:
      • (>) 大于 - $gt
      • (<) 小于 - $lt
      • (>=) 大于等于 - $gte
      • (<= ) 小于等于 - $lte

MongoDB 与 RDBMS Where 语句比较
如果你熟悉常规的 SQL 数据,通过下表可以更好的理解 MongoDB 的条件语句查询:

操作 格式 范例 RDBMS中的类似语句
等于 {<key>:<value>} db.col.find({"by":"菜鸟教程"}).pretty() where by = '菜鸟教程'
小于 {<key>:{$lt:<value>}} db.col.find({"likes":{$lt:50}}).pretty() where likes < 50
小于或等于 {<key>:{$lte:<value>}} db.col.find({"likes":{$lte:50}}).pretty() where likes <= 50
大于 {<key>:{$gt:<value>}} db.col.find({"likes":{$gt:50}}).pretty() where likes > 50
大于或等于 {<key>:{$gte:<value>}} db.col.find({"likes":{$gte:50}}).pretty() where likes >= 50
不等于 {<key>:{$ne:<value>}} db.col.find({"likes":{$ne:50}}).pretty() where likes != 50
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容