python写爬虫3-MongoDB数据缓存(采集58出租房信息)

2023-12-07 03:20

本文主要是介绍python写爬虫3-MongoDB数据缓存(采集58出租房信息),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

python写爬虫3-MongoDB数据缓存(采集58出租房信息)

有时,我们下载某个页面并抓取部分数据后,之后可能还会需要重新下载该页面,抓取其他数据。对于小网站而言,这不算什么大问题;但对于那些拥有百万网页的网站来说,重新爬取可能需要耗费大量时间。因此,我们可以对已爬取的网页进行缓存,让每个页面只下载一次。

本文代码只是实现了数据的存储与获取,与上述案例实情不符
开发环境:
1.硬件mac
2.python2.7
3.MongoDB3.4.2

NoSQL即Not Only SQL,通常是无模式的,NoSQL包含列数据存储(HBase),键值对存储(Redis),面向文档的数据库(MongoDB),图形数据库(Neo4j);本文采用MongoDB,MongoDB有个功能:为数据设定时间,当到达设定时间后,MongoDB可自动为我们删除记录。

需注意,MongoDB缓存无法按设定时间精确清理过期记录,会存在1分钟内的延迟,这是MongoDB的运行机制造成的

1.安装MongoDB及对应的Python封装库

mac下安装MongoDB命令:

brew update
brew install mongodb
pip install pymongo

2.配置MongoDB

创建默认MongoDB数据库文件存放目录

mkdir -p /data/db

记得给此目录加用户的读写权限,不然会报权限错误;其他配置,请参见官方文档。

3.启动MongoDB

mongod

4.MongoDB缓存实现

#!/usr/bin/env python
# -*- coding: utf-8 -*-import pickle
import zlib
from bson.binary import Binary
from datetime import datetime, timedelta
from pymongo import MongoClientclass MongoCache:def __init__(self, client=None, expires=timedelta(days=1)):self.client = MongoClient('localhost', 27017)self.db = self.client.cacheself.db.webpage.create_index('timestamp', expireAfterSeconds=expires.total_seconds())def __getitem__(self, item):record = self.db.webpage.find_one({'id': item})if record:return pickle.loads(zlib.decompress(record['result']))  # 压缩数据else:return None# raise KeyError(item + 'dose not exist')def __setitem__(self, key, value):record = {'result': Binary(zlib.compress(pickle.dumps(value))), 'timestamp': datetime.utcnow()}self.db.webpage.update({'id': key}, {'$set': record}, upsert=True)

5.爬虫编写

先看一下http://bj.58.com/zufang/页面结构:
这里写图片描述
再看一下出租房详细页面结构:
这里写图片描述
下面开始敲代码:

#! /usr/bin/env python
# -*- coding:utf-8 -*-import urllib2
import lxml.html
import time
from lxml.cssselect import CSSSelector
from MongoCache import MongoCachedef download(url, user_agent='Google', num_retries=2):"""下载整个页面"""print 'Downloading:', url# 设置用户代理headers = {'User-agent': user_agent}request = urllib2.Request(url, headers=headers)try:html = urllib2.urlopen(request).read()except urllib2.URLError as e:print 'Downloading error:', e.reasonhtml = None# 只有在服务器报500-600错误时,才会重试下载,仅重试2次if num_retries > 0:if hasattr(e, 'code') and 500 <= e.code < 600:return download(url, num_retries-1)return htmldef get_data(url):"""从详细页面 获取各字段数据"""#  如果缓存中有该页面数据,则直接获取使用;否则,先下载页面,再使用cache = MongoCache()if not cache.__getitem__(url):html_text_detail = download(url)if not html_text_detail:passelse:cache.__setitem__(url, html_text_detail)else:print 'Exists:', urlhtml_text_detail = cache.__getitem__(url)try:#  获取个字段数据tree = lxml.html.fromstring(html_text_detail)house_title = CSSSelector('div.main-wrap > div.house-title > h1')house_pay_way1 = CSSSelector('div.house-pay-way > span:nth-child(1)')house_pay_way2 = CSSSelector('div.house-pay-way > span:nth-child(2)')print house_title(tree)[0].text_content()print '%s|%s' % (house_pay_way1(tree)[0].text_content(), house_pay_way2(tree)[0].text_content())for i in range(7):for j in range(2):css = 'div.house-desc-item > ul.f14 > li:nth-child(%s) > span:nth-child(%s)' % (i+1, j+1)house_info = CSSSelector(css)print house_info(tree)[0].text_content().replace(' ', '')except TypeError as e:print 'HTML文本发生错误:%s' % eexcept IndexError as e:print '获取详细数据发生错误:%s' % edef get_url(html):"""获取需爬取数据的链接集"""tree = lxml.html.fromstring(html)sel = CSSSelector('div.mainbox > div.main > div.content > div.listBox > ul.listUl > li > div.des > h2 > a')url_list = []for i in sel(tree):if i.get('href') not in url_list:url_list.append(i.get('href'))return url_listif __name__ == '__main__':url_index = 'http://bj.58.com/chuzu/'html_text_list = download(url_index)url_list = get_url(html_text_list)for url_detail in url_list:time.sleep(2)  # 延时2sget_data(url_detail)

执行效果图:(左屏为数据抓取输出;右屏为MongoDB数据库)
这里写图片描述

这篇关于python写爬虫3-MongoDB数据缓存(采集58出租房信息)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/464322

相关文章

Python实现AVIF图片与其他图片格式间的批量转换

《Python实现AVIF图片与其他图片格式间的批量转换》这篇文章主要为大家详细介绍了如何使用Pillow库实现AVIF与其他格式的相互转换,即将AVIF转换为常见的格式,比如JPG或PNG,需要的小... 目录环境配置1.将单个 AVIF 图片转换为 JPG 和 PNG2.批量转换目录下所有 AVIF 图

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.

详解如何通过Python批量转换图片为PDF

《详解如何通过Python批量转换图片为PDF》:本文主要介绍如何基于Python+Tkinter开发的图片批量转PDF工具,可以支持批量添加图片,拖拽等操作,感兴趣的小伙伴可以参考一下... 目录1. 概述2. 功能亮点2.1 主要功能2.2 界面设计3. 使用指南3.1 运行环境3.2 使用步骤4. 核

Python 安装和配置flask, flask_cors的图文教程

《Python安装和配置flask,flask_cors的图文教程》:本文主要介绍Python安装和配置flask,flask_cors的图文教程,本文通过图文并茂的形式给大家介绍的非常详细,... 目录一.python安装:二,配置环境变量,三:检查Python安装和环境变量,四:安装flask和flas

使用Python自建轻量级的HTTP调试工具

《使用Python自建轻量级的HTTP调试工具》这篇文章主要为大家详细介绍了如何使用Python自建一个轻量级的HTTP调试工具,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下... 目录一、为什么需要自建工具二、核心功能设计三、技术选型四、分步实现五、进阶优化技巧六、使用示例七、性能对比八、扩展方向建

基于Python打造一个可视化FTP服务器

《基于Python打造一个可视化FTP服务器》在日常办公和团队协作中,文件共享是一个不可或缺的需求,所以本文将使用Python+Tkinter+pyftpdlib开发一款可视化FTP服务器,有需要的小... 目录1. 概述2. 功能介绍3. 如何使用4. 代码解析5. 运行效果6.相关源码7. 总结与展望1

使用Python实现一键隐藏屏幕并锁定输入

《使用Python实现一键隐藏屏幕并锁定输入》本文主要介绍了使用Python编写一个一键隐藏屏幕并锁定输入的黑科技程序,能够在指定热键触发后立即遮挡屏幕,并禁止一切键盘鼠标输入,这样就再也不用担心自己... 目录1. 概述2. 功能亮点3.代码实现4.使用方法5. 展示效果6. 代码优化与拓展7. 总结1.

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

Python基础文件操作方法超详细讲解(详解版)

《Python基础文件操作方法超详细讲解(详解版)》文件就是操作系统为用户或应用程序提供的一个读写硬盘的虚拟单位,文件的核心操作就是读和写,:本文主要介绍Python基础文件操作方法超详细讲解的相... 目录一、文件操作1. 文件打开与关闭1.1 打开文件1.2 关闭文件2. 访问模式及说明二、文件读写1.

Python将博客内容html导出为Markdown格式

《Python将博客内容html导出为Markdown格式》Python将博客内容html导出为Markdown格式,通过博客url地址抓取文章,分析并提取出文章标题和内容,将内容构建成html,再转... 目录一、为什么要搞?二、准备如何搞?三、说搞咱就搞!抓取文章提取内容构建html转存markdown