我是靠谱客的博主 负责纸鹤,最近开发中收集的这篇文章主要介绍scrapy mysql 实例,8. Scrapy爬虫案例实战 - Python 全栈,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

任务:爬取腾讯网中关于指定条件的所有社会招聘信息,搜索条件为北京地区,Python关键字的就业岗位,并将信息存储到MySql数据库中。

实现思路:首先爬取每页的招聘信息列表,再爬取对应的招聘详情信息

① 创建项目

在命令行编写下面命令,创建项目tencent

scrapy startproject tencent

项目目录结构:

tencent

├── tencent

│ ├── __init__.py

│ ├── __pycache__

│ ├── items.py # Items的定义,定义抓取的数据结构

│ ├── middlewares.py # 定义Spider和DownLoader的Middlewares中间件实现。

│ ├── pipelines.py # 它定义Item Pipeline的实现,即定义数据管道

│ ├── settings.py # 它定义项目的全局配置

│ └── spiders # 其中包含一个个Spider的实现,每个Spider都有一个文件

│ ├── __init__.py

│ └── __pycache__

└── scrapy.cfg #Scrapy部署时的配置文件,定义了配置文件路径、部署相关信息等内容

② 进入tencent项目目录,创建爬虫spider类文件(hr招聘信息)

执行genspider命令,第一个参数是Spider的名称,第二个参数是网站域名。

scrapy genspider hr hr.tencent.com

$ tree

├── tencent

│ ├── __init__.py

│ ├── __pycache__

│ │ ├── __init__.cpython-36.pyc

│ │ └── settings.cpython-36.pyc

│ ├── items.py

│ ├── middlewares.py

│ ├── pipelines.py

│ ├── settings.py

│ └── spiders

│ ├── __init__.py

│ ├── __pycache__

│ │ └── __init__.cpython-36.pyc

│ └── hr.py #在spiders目录下有了一个爬虫类文件hr.py

└── scrapy.cfg

# hr.py的文件代码如下:

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

import scrapy

class HrSpider(scrapy.Spider):

name = 'hr'

allowed_domains = ['hr.tencent.com']

start_urls = ['https://hr.tencent.com/position.php?keywords=python&lid=2156']

def parse(self, response):

#解析当前招聘列表信息的url地址:

detail_urls = response.css('tr.even a::attr(href),tr.odd a::attr(href)').extract()

#遍历url地址

for url in detail_urls:

#fullurl = 'http://hr.tencent.com/' + url

#构建绝对的url地址,效果同上(域名加相对地址)

fullurl = response.urljoin(url)

print(fullurl)

测试一下获取第一页的招聘详情url地址信息

③ 创建Item

Item是保存爬取数据的容器,它的使用方法和字典类型,但相比字典多了些保护机制。

创建Item需要继承scrapy.Item类,并且定义类型为scrapy.Field的字段:

职位id号,名称、位置、类别、要求、人数、工作职责、工作要求

具体代码如下:(创建一个类名为HrItem)

import scrapy

class TencentItem(scrapy.Item):

# define the fields for your item here like:

# name = scrapy.Field()

pass

class HrItem(scrapy.Item):

'''

人事招聘信息封装类

(职位id号,名称、位置、类别、要求、人数、职责和要求)

'''

table = "hr" #表名

id = scrapy.Field()

title = scrapy.Field()

location = scrapy.Field()

type = scrapy.Field()

number = scrapy.Field()

duty = scrapy.Field()

requirement = scrapy.Field()

④ 解析Response

在hr.py文件中,parse()方法的参数response是start_urls里面的链接爬取后的结果。

提取的方式可以是CSS选择器、XPath选择器或者是re正则表达式。

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

import scrapy

from tencent.items import HrItem

class HrSpider(scrapy.Spider):

name = 'hr'

allowed_domains = ['hr.tencent.com']

start_urls = ['https://hr.tencent.com/position.php?keywords=python&lid=2156']

def parse(self, response):

#解析当前招聘列表信息的url地址:

detail_urls = response.css('tr.even a::attr(href),tr.odd a::attr(href)').extract()

#遍历url地址

for url in detail_urls:

#fullurl = 'http://hr.tencent.com/' + url

#构建绝对的url地址,效果同上(域名加相对地址)

fullurl = response.urljoin(url)

#print(fullurl)

# 构造请求准备爬取招聘详情信息,并指定由parse_page()方法解析回调函数

yield scrapy.Request(url=fullurl,callback=self.parse_page)

#获取下一页的url地址

next_url = response.css("#next::attr(href)").extract_first()

#判断若不是最后一页

if next_url != "javascript:;":

url = response.urljoin(next_url)

#构造下一页招聘列表信息的爬取

yield scrapy.Request(url=url,callback=self.parse)

# 解析详情页

def parse_page(self,response):

#构造招聘信息的Item容器对象

item = HrItem()

# 解析id号信息,并封装到Item中

item["id"] = response.selector.re_first('οnclick="applyPosition(([0-9]+));"')

#标题

item["title"] = response.css('#sharetitle::text').extract_first()

#位置

item["location"] = response.selector.re_first('工作地点:(.*?)')

#类别

item["type"] = response.selector.re_first('职位类别:(.*?)')

#人数

item["number"] = response.selector.re_first('招聘人数:([0-9]+)人')

#工作职责

duty = response.xpath('//table//tr[3]//li/text()').extract()

item["duty"] = ''.join(duty)

#工作要求

requirement = response.xpath('//table//tr[4]//li/text()').extract()

item["requirement"] = ''.join(requirement)

#print(item)

#交给管道文件

yield item

⑤、创建数据库和表:

在mysql中创建数据库mydb和数据表hr

CREATE TABLE `hr` (

`id` int(10) unsigned NOT NULL AUTO_INCREMENT,

`title` varchar(255) DEFAULT NULL,

`location` varchar(32) DEFAULT NULL,

`type` varchar(32) DEFAULT NULL,

`number` varchar(32) DEFAULT NULL,

`duty` text DEFAULT NULL,

`requirement` text DEFAULT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8

⑥、使用Item Pipeline

在Item管道文件中,定义一个MysqlPipeline,负责连接数据库并执行信息写入操作

import pymysql

class TencentPipeline(object):

def process_item(self, item, spider):

return item

class MysqlPipeline(object):

def __init__(self,host,user,password,database,port):

self.host = host

self.user = user

self.password = password

self.database = database

self.port = port

@classmethod

def from_crawler(cls,crawler):

return cls(

host = crawler.settings.get("MYSQL_HOST"),

user = crawler.settings.get("MYSQL_USER"),

password = crawler.settings.get("MYSQL_PASS"),

database = crawler.settings.get("MYSQL_DATABASE"),

port = crawler.settings.get("MYSQL_PORT"),

)

def open_spider(self, spider):

'''负责连接数据库'''

self.db = pymysql.connect(self.host,self.user,self.password,self.database,charset="utf8",port=self.port)

self.cursor = self.db.cursor()

def process_item(self, item, spider):

'''执行数据表的写入操作'''

#组装sql语句

data = dict(item)

keys = ','.join(data.keys())

values=','.join(['%s']*len(data))

sql = "insert into %s(%s) values(%s)"%(item.table,keys,values)

#指定参数,并执行sql添加

self.cursor.execute(sql,tuple(data.values()))

#事务提交

self.db.commit()

return item

def close_spider(self, spider):

'''关闭连接数据库'''

self.db.close()

⑦ 修改配置文件

打开配置文件:settings.py 开启并配置ITEM_PIPELINES信息,配置数据库连接信息

当有CONCURRENT_REQUESTS,没有DOWNLOAD_DELAY 时,服务器会在同一时间收到大量的请求。

当有CONCURRENT_REQUESTS,有DOWNLOAD_DELAY 时,服务器不会在同一时间收到大量的请求。

# 忽略爬虫协议

ROBOTSTXT_OBEY = False

# 并发量

CONCURRENT_REQUESTS = 1

#下载延迟

DOWNLOAD_DELAY = 0

ITEM_PIPELINES = {

#'educsdn.pipelines.EducsdnPipeline': 300,

'educsdn.pipelines.MysqlPipeline': 301,

}

MYSQL_HOST = 'localhost'

MYSQL_DATABASE = 'mydb'

MYSQL_USER = 'root'

MYSQL_PASS = ''

MYSQL_PORT = 3306

⑧、运行爬取:

执行如下命令来启用数据爬取

scrapy crawl hr

最后

以上就是负责纸鹤为你收集整理的scrapy mysql 实例,8. Scrapy爬虫案例实战 - Python 全栈的全部内容,希望文章能够帮你解决scrapy mysql 实例,8. Scrapy爬虫案例实战 - Python 全栈所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部