项目简介

利用scrapy抓取51job上的python招聘信息,关键词为“python”,范围:全国

利用redis的set数据类型保存抓取过的url,现实避免重复抓取;

利用脚本实现每隔一段时间,网站更新后自动抓取;

利用mongo和mysql,分别保存抓取结果。

主要内容

网站分析

进入51job后,输入关键字python,搜索范围改为全国,通过分析得到该网页为静态网页

搜索后生成的url即为开始抓取的url:https://search.51job.com/list/000000,000000,0000,00,9,99,python,2,1.html

明确抓取字段

编写items.py文件,明确要抓取的字段

import scrapy

class QcItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
# 数据来源
source = scrapy.Field()
# 抓取时间
utc_time = scrapy.Field() # 职位名称
work_position = scrapy.Field()
# 公司名称
name_company = scrapy.Field()
# 工作地点
work_place = scrapy.Field()
# 薪资范围
salary = scrapy.Field()
# 发布时间
publish_time = scrapy.Field() # 工作详情
content = scrapy.Field()
# 联系方式
contact = scrapy.Field()

编写爬虫文件

来到爬虫文件后,考虑给每一个请求添加一个请求头信息,因此,在下载中间件中添加请求头中间件

class QcSpiderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the spider middleware does not modify the
# passed objects. def process_request(self, request, spider):
"""
给每一个请求随机分配一个代理
:param request:
:param spider:
:return:
"""
user_agent = random.choice(ua)
request.headers['User-Agent'] = user_agent

添加请求头后,来到爬虫文件,编写parse函数,解析数据:

class QcSpider(scrapy.Spider):
name = 'qc'
# allowed_domains = ['51job.com'] # 开始url
start_urls = ['https://search.51job.com/list/000000,000000,0000,00,9,99,python,2,1.html'] def parse(self, response):
# 先编写下载中间件,给每个请求加一个User-Agent
# 解析数据
node_list = response.xpath('//div[@class="el"]')
for node in node_list: # 匹配详情页链接,观察51job发现前面4个节点不是招聘信息,因此也没有详情页
# 因此,取不到详情页链接,表示可以忽略,不用存
detail_link = node.xpath('./p/span/a/@href')
if detail_link:
item = QcItem()
item['work_position'] = node.xpath('./p/span/a/@title').extract_first()
item['name_company'] = node.xpath('./span[@class="t2"]/a/text()').extract_first()
item['work_place'] = node.xpath('./span[@class="t3"]/text()').extract_first()
item['salary'] = node.xpath('./span[@class="t4"]/text()').extract_first()
item['publish_time'] = node.xpath('./span[@class="t5"]/text()').extract_first() # 解析详情页数据
yield scrapy.Request(detail_link.extract_first(), callback=self.parse_detail, meta={"item": item})

在开始解析详情页数据之前,中下载中间件中,搭建redis,利用redis的set数据类型,将每一个详情页的链接添加到数据库中;

实现避免重复抓取,如果详情页的url在redis中,则忽略该次请求。

class QcRedisMiddleware(object):
"""
将第一个页面上的每一个url放入redis的set类型中,防止重复爬取
"""
# 连接redis
def __init__(self):
self.redis = redis.StrictRedis(host='localhost', port=6379, db=1) def process_request(self, request, spider): # 将来自详情页的链接存到redis中
if request.url.startswith("https://jobs.51job.com/"):
# MD5加密详情页链接
url_md5 = hashlib.md5(request.url.encode()).hexdigest() # 添加到redis,添加成功返回True,否则返回False
result = self.redis.sadd('qc_url', url_md5) # 添加失败,说明链接已爬取,忽略该请求
if not result:
raise IgnoreRequest

继续来到爬虫文件中,编写详情页数据解析的内容。

   def parse_detail(self, response):
item = response.meta['item']
# 编写下载中间件,将详情页链接存到redis中,达到去重复的目的 # 解析页面所有数据
content = response.xpath('//div[@class="bmsg job_msg inbox"]').xpath('string(.)').extract() # content = response.xpath('//div[@class="bmsg job_msg inbox"]/*/text()').extract()
# 取联系方式
contact = response.xpath('//div[@class="bmsg inbox"]/p/text()').extract() # 拿到的content有空格和换行符,利用正则,去掉空白符
item['content'] = re.sub('\s', '', ''.join(content))
item['contact'] = ''.join(contact).strip() yield item

此时,索要解析的数据均解析完毕,接下来就是将解析的数据进行保存。

数据保存

编写pipelines.py文件,保存item。利用mongo和mysql两种方式分别保存数据。

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
import json
import pymongo
import pymysql
from datetime import datetime class QcPipeline(object):
def process_item(self, item, spider): # 添加数据源
item['source'] = spider.name # 添加爬取时间
item['utc_time'] = str(datetime.utcnow()) return item class QcJsonPipeline(object):
"""
保存为json数据
"""
def open_spider(self, spider): # 打开文件
self.file = open('qc.json', 'a', encoding='utf-8') def process_item(self, item, spider): content = json.dumps(dict(item), ensure_ascii=False) + '\n'
self.file.write(content) return item def close_spider(self, spider):
self.file.close() class QcMongoPipeline(object):
"""
存入大Mongodb中
"""
def open_spider(self, spider): # 实例化mongo客户端并链接
self.client = pymongo.MongoClient(host='localhost', port=27017)
# 创建库和集合
self.collection = self.client['qc']['qc'] def process_item(self, item, spider):
# 添加数据
self.collection.insert(dict(item)) return item def close_spider(self, spider):
# 关闭数据库
self.client.close() class QcMysqlPipeline(object):
"""
数据存入到mysql
"""
def open_spider(self, spider):
self.conn = pymysql.connect(
host='localhost',
port=3306,
database='qc',
user='z',
password='',
charset='utf8'
)
# 实例一个游标
self.cursor = self.conn.cursor() def process_item(self, item, spider): sql = ("insert into qc(source, utcTime, workName, "
"company, workPosition, salary, publishTime, "
"content, contact)"
"values (%s, %s, %s, %s, %s, %s, %s, %s, %s)") list_item = [item['source'], item['utc_time'], item['work_position'],
item['name_company'], item['work_place'], item['salary'], item['publish_time'],
item['content'], item['contact']] self.cursor.execute(sql, list_item)
# 提交数据
self.conn.commit() return item def close_spider(self, spider):
self.cursor.close()
self.conn.close() # create table qc
# (
# id INT unsigned PRIMARY KEY auto_increment NOT NULL,
# source VARCHAR(20) DEFAULT "",
# utcTime DATETIME DEFAULT "1111-11-11 11:11:11",
# workName VARCHAR(40) DEFAULT "",
# company VARCHAR(40) DEFAULT "",
# workPosition VARCHAR(40) DEFAULT "",
# salary VARCHAR(40) DEFAULT "",
# publishTime VARCHAR(20) DEFAULT "",
# content TEXT(1024),
# contact VARCHAR(40) DEFAULT ""
# );

自动抓取

最后实现自动爬取,单独编写一个脚本文件,隔一段时间自动抓取。

from scrapy import cmdline
import time # cmdline.execute("scrapy crawl qc".split()) import os
import time while True:
"""
每隔10s自动爬取一次,实现自动更新
"""
os.system("scrapy crawl qc")
time.sleep(20)

完整代码

参见:https://github.com/zInPython/qiancheng

 

scrapy实现自动抓取51job并分别保存到redis,mongo和mysql数据库中的更多相关文章

  1. 使用pandas中的raad_html函数爬取TOP500超级计算机表格数据并保存到csv文件和mysql数据库中

    参考链接:https://www.makcyun.top/web_scraping_withpython2.html #!/usr/bin/env python # -*- coding: utf-8 ...

  2. 用selenium 自动爬取某一本小说章节及其内容,并存入数据库中

    from selenium import webdriver import pymysql from selenium.webdriver.support.ui import WebDriverWai ...

  3. IIS崩溃时自动抓取Dump

    背景:在客户现场,IIS有时会崩溃,开发环境没法重现这个bug,唯有抓取IIS的崩溃是的Dump文件分析. IIS崩溃时自动抓取Dump,需要满足下面几个条件 1.启动 Windows Error R ...

  4. scrapy自动抓取蛋壳公寓最新房源信息并存入sql数据库

    利用scrapy抓取蛋壳公寓上的房源信息,以北京市为例,目标url:https://www.dankegongyu.com/room/bj 思路分析 每次更新最新消息,都是在第一页上显示,因此考虑隔一 ...

  5. 学习笔记CB010:递归神经网络、LSTM、自动抓取字幕

    递归神经网络可存储记忆神经网络,LSTM是其中一种,在NLP领域应用效果不错. 递归神经网络(RNN),时间递归神经网络(recurrent neural network),结构递归神经网络(recu ...

  6. SQL Server定时自动抓取耗时SQL并归档数据发邮件脚本分享

    SQL Server定时自动抓取耗时SQL并归档数据发邮件脚本分享 第一步建库和建表 USE [master] GO CREATE DATABASE [MonitorElapsedHighSQL] G ...

  7. [转]使用scrapy进行大规模抓取

    原文:http://www.yakergong.net/blog/archives/500 使用scrapy有大概半年了,算是有些经验吧,在这里跟大家讨论一下使用scrapy作为爬虫进行大规模抓取可能 ...

  8. 自动抓取java堆栈

    参数1 进程名字,参数2 最大线程数 例: pid为8888,达到1000个线程时自动抓取堆栈信息 ./autojstack.sh 8888 1000 & #!/bin/bashfileNam ...

  9. SQL Server定时自动抓取耗时SQL并归档数据脚本分享

    原文:SQL Server定时自动抓取耗时SQL并归档数据脚本分享 SQL Server定时自动抓取耗时SQL并归档数据脚本分享 第一步建库 USE [master] GO CREATE DATABA ...

随机推荐

  1. NetworkManager网络通讯_NetworkManager(二)

    本文主要来实现一下自定UI(实现HUD的功能),并对Network Manger进行深入的讲解. 1)自定义manager 创建脚本CustomerUnetManger,并继承自NetworkMang ...

  2. AssetBundle异步加载被中断的问题

    刘 刘泰言创建于 1 年前 在使用异步接口 yield return AssetBundle.ASyncLoad的时候,难免会想到:这个异步处理完之前如何Cancel掉这个任务?也就是一个AssetB ...

  3. 【排列组合】给定一个M*N的格子或棋盘,从左下角走到右上角的走法总数(每次只能向右或向上移动一个方格边长的距离)

    版权声明:本文为CSDN博主「梵解君」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明. 原文链接:https://blog.csdn.net/hadeso/art ...

  4. vue---Excel表格导出

    一.安装依赖 npm install file-saver --save npm install xlsx --save npm install script-loader --save-dev 二. ...

  5. [Spark]Spark-streaming通过Receiver方式实时消费Kafka流程(Yarn-cluster)

    1.启动zookeeper 2.启动kafka服务(broker) [root@master kafka_2.11-0.10.2.1]# ./bin/kafka-server-start.sh con ...

  6. windows下安装nginx和基本配置

    1.下载并安装nginx 到nginx官网上下载相应的安装包,http://nginx.org/en/download.html: 下载之后进行解压,将解压后的文件放到自己心仪的目录下,如下图所示: ...

  7. 6.1Hadoop属性Configuration配置API

    6.1  Hadoop属性配置API Hadoop需要添加一些自定义的属性值,可以通过Configuration类的实例来加载xml配置文件中的属性值. (1)   xml配置文件的格式 <?x ...

  8. 大数据之路week01--自学之集合_2(列表迭代器 ListIterator)

    列表迭代器: ListIterator listerator():List集合特有的迭代器 该迭代器继承了Iterator迭代器,所以,就可以直接使用hasNext()和next()方法 特有功能: ...

  9. re模块的基本使用

    目录 re模块 常用元字符 特殊构造 贪婪模式 非贪婪模式 re的常用函数 re模块补充 关于re模块必须知道的知识点 re模块 re模块 , 即正则表达式 , 本身是一种小型的.高度专业化的编程语言 ...

  10. 2019年10月11号 王庆超 linux

    1.计算机操作系统简介 (1)掌握操作系统的定义:操作系统是一个用来协调.管理和控制计算机硬件和软件资源的系统 程序,它位于硬件和应用程序之间. (2)掌握操作系统的内核的定义:操作系统的内核是一个管 ...