scrapy 爬取网上租房信息

一、背景

为了分析一线城市的房价在工资的占比,我用Python分别爬取了自如以及拉勾的数据。(见公众号「Crossin的编程教室」今天第1条推送)
本文使用 scrapy 进行爬取自如所有城市的租房信息。
数据预览:

二、创建项目

本文使用 CrawlSpider 进行爬取。普通的 spider ,解析完一整个页面后获取下一页 url,然后重新发送新请求。CrawlSpider 可以在设置只要满足某个条件的url,都进行爬取,就不需要手动的 yield request。
代码:
rules = (        # 设置爬取需要爬取城市url的正则表达式 Rule(LinkExtractor(allow=r'http://.*\.ziroom.com/z\/.*/\?isOpen=0'), follow=True),        # follow =True,不然只会爬到第四页,不会进行跟进爬取 Rule(LinkExtractor(allow=r'http://.*\.ziroom.com/z\/.*d\d+-p\d+\/'),callback="parse_page", follow=True),    )
创建 CrawlSpider 爬虫:
1.创建项目scrapy startproject ziroom2.进入项目所在路径 cd ziroom3.创建爬虫 scrapy genspider -t ziroom_spider "域名"4.scrapy genspider -t ziroom_spider "www.ziroom.com"

三、数据抓取

首先打开这个链接 http://www.ziroom.com/z/z0/ 进行分析。找到房源信息,我们的目的就是将标题,价格,位置,地铁情况等基本信息抓取出来,所以就没有必要去爬取进入详情页爬取。然后点击“下一页”可以发现,url会随之变化,例如http://www.ziroom.com/z/z0-p2/ 第二页为p2,第一页是p1,说明房源信息并不是通过Ajax异步请求技术得到的,这就好办了,我们直接请求浏览器显示的url,并使用xpath,CSS或者正则提取信息就行了。
打开浏览器F12,进入开发者工具,选择Elements,定位任一房源标题,就能找到我们所需要的数据。可以看到房源

我可以看到房源数据是存放在列表中,我使用Xpath进行提取。

可以看到上面的代码还没有提取价格,这是因为自如网的价格有个小坑,房屋价格信息是图片,图片上的数字都是乱序,前端从这张图片根据像素截取出来数字,来展示价格。

复制url打开就可以看到如下的图片,有10个数字。

最开始想到的是使用百度的图像识别API接口,但是去看了看,发现免费的调用次数只有200,网上说这个图片的url是随机的,如果真这样,那肯定要花钱,要么使用pytesseract,或者自己写代码。但是我不想自己造轮子,且安装 pytesseract 这个也挺麻烦。这时候我想,要是图片的url并不是随机的就好了,所以我爬了北京所有的租房信息,发现图片的url并不是网上所说的随机的,总共只有10个url是固定的。这就简单了。

我先用百度图像识别,识别出图片中的数字,并根据background-position 确定切割数字的位置,然后组合就能得到价格。例如-171.2px代表的位置是 8,对应的就是上图中的数字 2。通过观察发现,对应位置有如下几个。

['-0px', '-21.4px', '-42.8px', '-64.2px', '-85.6px', '-107px', '-128.4px', '-149.8px', '-171.2px', '-192.6px']

所以只需要将房源价格中图片的url与10个url进行对比,就能确定图片的数字。代码如下

四、数据存储

表结构
设置items.py
class ZiroomItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field()    # 固定写法 title = scrapy.Field() desc = scrapy.Field() location = scrapy.Field() region = scrapy.Field() prices_url = scrapy.Field() price = scrapy.Field() room_url = scrapy.Field()    city = scrapy.Field()
设置好item后要在spider.py中导入item
from ziroom.items import ZiroomItem item = ZiroomItem( title = title, desc = desc, location = location, region = region, prices_url = prices_url, price = price, room_url = room_url, city = self.city,            )
设置pipelines.py。这里只贴出异步存储的代码,同步存储所使用的的代码可以在完整代码查看。
# 异步插入,速度快class TwistedPipeline(object): def __init__(self): dbparams = { 'host': '127.0.0.1', 'port': 3306, 'user': 'root', 'password': '1234', 'database': 'ziroom', 'charset': 'utf8', 'cursorclass': cursors.DictCursor # 需要指定游标的类 } # 设置连接池 self.dbpool = adbapi.ConnectionPool('pymysql',**dbparams) self._sql = None
@property def sql(self): if not self._sql: self._sql = """ insert into city(Id, title, area, location, city, region, price,room_url, price_url) values(null,%s,%s,%s,%s,%s,%s,%s,%s) """ return self._sql return self._sql
def process_item(self, item, spider): # 将insert_item 给 runInteraction 执行就可以实现异步 defer = self.dbpool.runInteraction(self.insert_item, item) # 添加错误处理,想知道是哪个 item 出错,所以传入 item 参数,同理传入 spider defer.addErrback(self.handle_error,item, spider)
# item 是 process_item def insert_item(self, cursor, item): cursor.execute(self.sql,(item['title'],item['desc'],item['location'],item['city'],item['region'],item['price'], item['room_url'],item['prices_url'])) # 添加错误处理 def handle_error(self,errors,item,spider): print("="*10) print(errors) print("="*10)
设置middlewares.py,我这里只设置了随机 UserAgent。设置随机IP也可以在middlewares进行设置。
from scrapy import signalsimport randomclass UserAgentDownloadMiddleware(object): def process_request(self, request,spider): USER_AGENTS = [ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36", "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML like Gecko) Chrome/44.0.2403.155 Safari/537.36", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36", "Mozilla/5.0 (X11; Linux i686; rv:64.0) Gecko/20100101 Firefox/64.0", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0", "Mozilla/5.0 (X11; Linux i586; rv:63.0) Gecko/20100101 Firefox/63.0", "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:63.0) Gecko/20100101 Firefox/63.0", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A", "Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.13+ (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; TencentTraveler 4.0; Trident/4.0; SLCC1; Media Center PC 5.0; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30618)", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; QQDownload 1.7; GTB6.6; TencentTraveler 4.0; SLCC1; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.5.30729; .NET CLR 3.0.30729)", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; iCafeMedia; TencentTraveler 4.0; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)", "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/418.8 (KHTML, like Gecko, Safari) Cheshire/1.0.UNOFFICIAL", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/418.9 (KHTML, like Gecko, Safari) Cheshire/1.0.UNOFFICIAL"
] user_agent = random.choice(USER_AGENTS) request.headers['User-Agent'] = user_agent

五、基本设置

修改setting.py:
1.ROBOTSTXT_OBEY = False # 设置为不遵守robot协议2.设置headersDEFAULT_REQUEST_HEADERS = {'Host': 'nj.ziroom.com','Accept-Language': 'zh-CN,zh;q=0.9',
'Upgrade-Insecure-Requests': '1', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'}3. 打开middlewaresDOWNLOADER_MIDDLEWARES = {'ziroom.middlewares.UserAgentDownloadMiddleware': 543}
4. 打开pipelinesITEM_PIPELINES = {'ziroom.pipelines.TwistedPipeline': 300}

六、运行爬虫

需要在项目目录下运行:

运行成功:

结束运行:

项目总体介绍和结果展示在今天的第 1 条推送文章中。
(0)

相关推荐

  • python-websocket爬虫案例

    一.今天做一个阿三的网站刚刚好是个websocket请求 精华都在这图上,和下面代码,没啥加密可以当个简单模板 目标网站url:https://m.jungleerummy.com/register ...

  • requests模块的入门使用

    requests模块的入门使用 dongge-destiny 2018-07-11 00:10:18  137  收藏 分类专栏: python-爬虫 文章标签: requests模块的入门使用 版权 ...

  • scrapy实践之settings的配置

    在scrapy创建的爬虫项目中,包括了以下4个基本文件 1. items.py 2. middlewares.py 3. pipelines.py 4. settings.py items定义了需要从 ...

  • 锲而不舍,爬虫的魂

    写爬虫经常被封锁,常用的策略有伪装成浏览器,降低访问频率,还有一个是修正一下重新爬.关于代理IP不在本文范畴,我们只需要够用的数据即可,一般一个IP,一台机器慢慢的爬就可以了. 分别看看这几个策略的实 ...

  • Python爬虫新手入门教学(四):爬取前程无忧招聘信息

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. Python爬虫.数据分析.网站开发等案例教程视频免费在线观看 https://space. ...

  • (3条消息) Python爬取全国高校信息并写入csv

    2021-03-23更新 原来的页面有一些小的改变, 原来的院校特效一列变成了现在的 一流大学建设高校 和一流学科建设高校 两列, 所以代码需要有一些改变,总的代码已经更新了,至于思路那部分就不改了. ...

  • 编程语言教你用python爬取唯品会商品信息,详细教程,仅供学习

    代码展示 运行结束来个照 信息保存到表格中 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手. 很多已经做案例的人,却不知道如何去学习更加 ...

  • python爬虫29 | 使用scrapy爬取糗事百科的例子,告诉你它有多厉害!

    是时候给你说说 爬虫框架了 使用框架来爬取数据 会节省我们更多时间 很快就能抓取到我们想要抓取的内容 框架集合了许多操作 比如请求,数据解析,存储等等 都可以由框架完成 有些小伙伴就要问了 你他妈的 ...

  • 使用 scrapy 爬取 stackoverflow 上的所有 Python 问答

    前两天 小帅b跟你 说了说分布式爬虫 在里面我就说到 弄个例子来体现一下分布式爬虫 在此之前 我们可以先写一个单机版的爬虫 往后再对其修改一些配置 就可以搞成分布式的了 所以这次我们先 爬取 stac ...

  • 爬取A股实时信息(单页篇)

    小勤:大海,上次看你用Powerquery爬取国际燃油价格的内容,觉得太好玩儿了.但国际燃油价格那个可能很多人都不关注,能不能来点更普适性的,比如股票? 大海:呵呵,当然可以啊.股票信息其实更容易一些 ...

  • Power BI(Query)爬取A股实时信息——单页篇

    小勤:大海,上次看你用Powerquery爬取国际燃油价格的内容,觉得太好玩儿了.但国际燃油价格那个可能很多人都不关注,能不能来点更普适性的,比如股票? 大海:呵呵,当然可以啊.股票信息其实更容易一些 ...

  • Excel PQ爬取A股实时信息——多页整合篇

    小勤:大海,上次你教我<爬取了沪深A股中的一页>内容,我练过了,这次,继续教我多爬取几个页面呗. 大海:嗯,其实爬取多几个页面跟爬取一个的方法是一样的,只是,一页一页的分开爬取了之后,要再 ...

  • 手把手教你爬取优酷电影信息-2

    上一章节中我们实现了对优酷单页面的爬取,简单进行回顾一下,使用HtmlAgilityPack库,对爬虫的爬取一共分为三步 爬虫步骤 加载页面 解析数据 保存数据 继第一篇文档后的爬虫进阶,本文章主要是 ...