php爬取房源,(python) scrapy抓取房天下房源信息

一、前言

研究房价走势和房源信息。

二、知识准备

1.python相关知识储备

2.对Scrapy框架有基本的了解,知道其运行流程和逻辑

3.Xpath和CSS选择器相关知识(本文只使用Xpath,要使用CSS选择器的同学请自行学习)

三、开始编码

1.新建工程

安装Scrapy过程就略过了,首先在通过命令 scrapy startproject shuofangwang新建工程,使用Pycharm打开可以看到其目录结构如下

2737066598.png

这些文件分别是:

scrapy.cfg: 项目的配置文件

shuofangwan/: 该项目的python模块。之后您将在此加入代码。

shuofangwan/items.py: 项目中的item文件.

shuofangwan/pipelines.py: 项目中的pipelines文件.

shuofangwan/settings.py: 项目的设置文件.

shuofangwan/spiders/: 放置spider代码的目录.

2.定义Item

Item 是保存爬取到的数据的容器,class HouseItem定义你要保存的数据。import scrapy

import sys

reload(sys)

sys.setdefaultencoding('utf-8')

class HouseItem(scrapy.Item):

HouseName = scrapy.Field() #楼盘名

HousePrice = scrapy.Field() #价格

HouseAddress = scrapy.Field() #区域

HouseDetailAddress = scrapy.Field() #详细地址

House_type = scrapy.Field() #户型

HouseComment = scrapy.Field() #留言条数

3.编写爬虫Spider

创建一个Spider,必须继承 scrapy.Spider 类, 且定义以下三个属性name: 用于区别Spider。 该名字必须是唯一的,您不可以为不同的Spider设定相同的名字。

start_urls: 包含了Spider在启动时进行爬取的url列表。 因此,第一个被获取到的页面将是其中之一。

后续的URL则从初始的URL获取到的数据中提取。

parse() 是spider的一个方法。 被调用时,每个初始URL完成下载后生成的 Response

对象将会作为唯一的参数传递给该函数。 该方法负责解析返回的数据(response

data),提取数据(生成item)以及生成需要进一步处理的URL的 Request 对象。

如下代码为我Spider主代码模块#!/usr/bin/env python

# coding:utf-8

import scrapy

import HouseItem

import sys

reload(sys)

sys.setdefaultencoding('utf-8')

class shuofangwnagSpider(scrapy.Spider):

name = "shuofangwang"

allowed_domains = ["newhouse.cs.fang.com"]

offset = 1

url = "http://newhouse.cs.fang.com/house/s/b9"

start_urls = [url + str(offset)+'/']

def parse(self, response):

clears = response.xpath("//div[@class='nlc_details']")

for each in clears:

item = HouseItem.HouseItem()

house_address = each.xpath(".//div[@class='address']")

item['HouseDetailAddress'] = house_address.xpath('.//a/@title').extract()

item['HouseAddress'] = house_address.xpath('.//a/span/text()').extract()

housetypelist = each.xpath(".//div[@class='house_type clearfix']")

item['House_type'] = housetypelist.xpath('string(.)').extract()

house_price = each.xpath(".//div[@class='nhouse_price']")

item['HousePrice'] = house_price.xpath('.//span/text()').extract()

houseeach = each.xpath(".//div[@class='nlcd_name']")

item['HouseName'] = houseeach.xpath('.//a/text()').extract()

item['HouseComment'] = each.xpath(".//span[@class='value_num']/text()").extract()

yield item

if self.offset < 31:

self.offset += 1

yield scrapy.Request(self.url + str(self.offset)+'/', callback = self.parse)

4.数据处理

编写ITEM_PIPELINES处理数据,Scrapy允许数据以JSON、JSON lines、CSV、XML四种格式保存,由于需要进行后续数据统计工作所以保存为CSV格式。在pipeline.py中写入代码:import json

import csv

import sys

reload(sys)

sys.setdefaultencoding('utf-8')

class ShuofangwangPipeline(object):

def __init__(self):

self.filename = open('items.csv', 'wb')

self.csvwriter = csv.writer(self.filename, delimiter=',')

self.csvwriter.writerow(['楼盘', '价格', '地址'])

def process_item(self, item, spider):

rows = zip(item['HouseName'], item['HousePrice'], item['HouseAddress'])

for row in rows:

self.csvwriter.writerow(row)

return item

def __init__(self):

self.filename = open('houseData.json', 'w')

def process_item(self, item, spider):

text = json.dumps(dict(item), ensure_ascii=False)+",\n"

self.filename.write(text.encode("utf-8").replace("\\t", "").replace("\\n",""))

print text

def close_spider(self,spider):

self.filename.close()

class Pipeline_ToCSV(object):

def __init__(self):

store_file = 'house.csv'

self.file = open(store_file, 'wb')

self.writer = csv.writer(self.file)

self.writer.writerow(("楼盘", "区域","价格","户型","评论" , "地址"))

def process_item(self, item, spider):

housename = str(item['HouseName']).replace('u\'', '\'').replace("\\t", "").replace("\\n","").replace("[","").replace("]","")

houseprice = str(item['HousePrice']).replace('u\'', '\'').replace("\\t", "").replace("\\n","").replace("[","").replace("]","")

houseaddress = str(item['HouseAddress']).replace('u\'', '\'').replace("\\t", "").replace("\\n","").replace("[","").replace("]","")

housedetailaddress = str(item['HouseDetailAddress']).replace('u\'', '\'').replace("\\t", "").replace("\\n","").replace("[","").replace("]","")

housetype = str(item['House_type']).replace('u\'', '\'').replace("\\t", "").replace("\\n","").replace("[","").replace("]","")

housecomment = str(item['HouseComment']).replace('u\'', '\'').replace("\\t", "").replace("\\n","").replace("[","").replace("]","")

housename1 = housename.decode("unicode-escape")

houseprice1 = houseprice.decode("unicode-escape")

houseaddress1 = houseaddress.decode("unicode-escape")

housedetailaddress1 = housedetailaddress.decode("unicode-escape")

housetype1 = housetype.decode("unicode-escape")

housecomment1 = housecomment.decode("unicode-escape")

print '1----'+housename1

print '2----'+houseprice1

print '3----'+houseaddress1

print '4----'+housedetailaddress1

print '5----'+housetype1

print '6----'+housecomment1

self.writer.writerow((housename1,houseaddress1, houseprice1, housetype1, housecomment1, housedetailaddress1))

return item

def close_spider(self,spider):

self.file.close()

然后在settings.py中加入如下代码:ITEM_PIPELINES = {

#'shuofangwang.pipelines.ShuofangwangPipeline': 1,

'shuofangwang.pipelines.Pipeline_ToCSV':2,

}

ShuofangwangPipeline和Pipeline_ToCSV对应的是pipelines.py中的两个类,第一个是存储为json格式的用于测试使用所以在工程后期对期进行屏蔽处理,第二个是存储CSV格式的。其名字后面的1和2代表着优先级。

代码中使用三个replace方法是因为取出的数据中含有"tn"等,其并不是我们想要的数据所以删除。

并且要 特别注意 的是extract()取出的数据是unicode编码后的数据,所以后期的处理一定要注意,这里在最后使用.decode("unicode-escape")对数据进行转码。

抓取日志信息和处理后的数据如下:

894352667.png

2395411147.png

四、总结

本文使用的知识点并不多,主要就是对scrapy框架的运行过程流程的了解,对数据处理时编码的处理。对我来说由于第一次使用python编码爬虫应用,最大的难点就是XPATH对数据的选取和数据存储时编码的处理。听说python3可以忽略编码的问题,后续可以进行尝试。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值