【Scrapy爬取实例】- 爬取链家网指定城市二手房源信息

文章目录

          • 一、网站分析
          • 二、抓取思路
          • 三、关键代码
          • 四、抓取结果(部分)

一、网站分析
  • 链接分析
    • 城市链接
      北京:https://bj.lianjia.com/ershoufang/
      成都:https://cd.lianjia.com/ershoufang/
      四川:https://sc.lianjia.com/ershoufang/

      可见,不同城市,将标红处改为城市的首字母小写即可。
    • 页面链接
      第一页:https://cd.lianjia.com/ershoufang/pg1
      第二页:https://cd.lianjia.com/ershoufang/pg2
      第三页:https://cd.lianjia.com/ershoufang/pg3

      可见,将标红处依次递增即可。
  • 数据加载方式
    链家的比较简单,网页源码里都有
    【Scrapy爬取实例】- 爬取链家网指定城市二手房源信息_第1张图片
  • 目标信息
    【Scrapy爬取实例】- 爬取链家网指定城市二手房源信息_第2张图片
    本次抓取目标为上图红框中的关键文字信息。
二、抓取思路

因为信息都在网页源码中,页面链接的生成规律也很简单,所以解决如何生成指定城市的链接即可。
由上述分析可知,城市链接只要将城市名称,如 重庆转为首字母小写 cq,再填入对应位置即可。
其他:

  • 设置请求头、免费代理ip实时切换,处理请求异常
  • 抓取到的信息存入mongodb
三、关键代码
  • item
import scrapy
class ErshoufangItem(scrapy.Item):
    # define the fields for your item here like: 
    title = scrapy.Field() #房屋title
    address = scrapy.Field() #地址
    city = scrapy.Field()#所在城市
    info = scrapy.Field()#具体信息
    totalPrice = scrapy.Field()#总价
    unitPrice = scrapy.Field()#单价
  • spider
import scrapy
from xpinyin import Pinyin #汉字转拼音的库

from ershoufang.items import ErshoufangItem

pinyin = Pinyin()
CRAWL_PAGE = 10 #爬取页数

class LianjiaSpider(scrapy.Spider):
    name = 'lianjia'
    def __init__(self,city_name):
        #city_name 由命令行传入
        self.city_name = city_name
        #城市链接,pinyin.get_initials(self.city_name,'').lower()将城市名称转为小写
        self.url = 'https://%s.lianjia.com/ershoufang/'%(pinyin.get_initials(self.city_name,'').lower())
    def start_requests(self):
        for i in range(2,CRAWL_PAGE+1):
            yield scrapy.Request(self.url+'pg%s'%str(i),callback=self.parse)

    def parse(self, response):
        dataList = response.css('ul.sellListContent li')
        for data in dataList:
            item = ErshoufangItem()
            item['title'] = data.css('div.title a::text').extract_first()
            item['address'] = '-'.join(data.css('div.positionInfo a::text').extract())
            item['city'] = self.city_name
            item['info'] = data.css('div.houseInfo::text').extract_first()
            totalPrice = data.css('div.totalPrice span::text').extract_first()
            item['totalPrice'] = totalPrice+'万' if totalPrice else '未出价'
            item['unitPrice'] = data.css('div.unitPrice span::text').extract_first()
            yield item

城市名称转拼音,用到了xpinyin这个库,可以去了解下
city_name 参数由命令行传入,如: scrapy crawl lianjia -a city_name=北京

  • 数据存储
    • mongdb操作封装
'''
 @author:jxc
 @function:mongodb常用方法封装
'''
from pymongo import MongoClient

from ershoufang.settings import MONGODB_CONNECT_URL
SUCCESS = True #操作成功
FAILED = False #操作失败

class Mongodb:
    def __init__(self,db_name):
        #连接的数据库
        try:
            self.db = MongoClient(MONGODB_CONNECT_URL).get_database(db_name)
        except Exception as e:
            raise AttributeError('db %s is not exist'%db_name)
            
    @property
    def collection(self):
        return self._collection
    '''
    获取操作的集合
    :param collection_name:集合名称
    '''    
    @collection.setter
    def collection(self,collection_name):
        try:
            self._collection = self.db.get_collection(collection_name)
        except Exception as e:
            raise AttributeError('collection %s is not exist'%collection_name)
        
    '''
     插入数据
     :param element:插入的数据,需为字典类型
    '''
    def insert(self,element):
        if isinstance(element,dict):
            try:
                self._collection.insert(element)
                return SUCCESS
            except Exception as e:
                print('发生异常:%s'%e.value)
                return FAILED
        raise TypeError('need a dict,but %s was given'%(type(element)))

    '''
    数据库查询
    :param collection_name:要操作的集合名称
    :param all:是否查询所有数据
    :param projection:查询显示的字段{字段名:0/1}  0-不显示  1-显示
    :param **kwargs:查询条件,可变长度参数,将传来的值转换为字典供函数调用
    '''
    def query(self,all=True,projection={},**kwargs):
        data = self._collection.find(kwargs,projection) if all else self._collection.find_one(kwargs,projection)
        return data
  • pipeline存储
from ershoufang.mongoUtil import Mongodb

class ErshoufangPipeline:
    def __init__(self):
        self.db = Mongodb('source') #连接到数据库

    def process_item(self, item, spider):
        self.db.collection = 'house' #设置要操作的集合
        self.db.insert(dict(item))
        return item
四、抓取结果(部分)

【Scrapy爬取实例】- 爬取链家网指定城市二手房源信息_第3张图片
博主其他系列文章:

[1] 【python实用特性】-切片

[2] 【python实用特性】- 迭代、可迭代对象、迭代器

[3] 【python实用特性】- 列表生成式

[4] 【python实用特性】- yield生成器

[5] 【python实用特性】- 装饰器

[6] Python如何爬取动态网页数据

[7] Python+selenium实现自动爬取实例

[8] Python自动化利器—robobrowser

你可能感兴趣的:(【Scrapy爬取实例】- 爬取链家网指定城市二手房源信息)