创建项目之类的,这里就不说了,直接丢代码了。
什么???你说你不会创建项目,不会整虚拟环境!前面章节有,先看基础!
spider.py
- 爬虫文件是Scrapy框架里面需要我们手写的最多的部分了,几乎全自己写
- 但是其他的文件很多都是配置信息,我们只需要跟着改改写写就好了
- 前面有说过
yield
,其实这里就和yield很像,大家如果用过生产消费模式,就简单了 - 我在这里简单说下,就是你的函数返回一个值的时候,不直接返回,或者存到一个全局变量里
- 在后面函数直接调用这个函数,或者是直接使用这个变量
import scrapy
from job.items import JobItem
from urllib.parse import quote # 查询字符串加密
class A51jobSpider(scrapy.Spider):
name = '51job'
allowed_domains = ['search.51job.com']
keyword = "%2520" # 去掉指定的岗位名称,全部数据10万条
start_urls = ['https://search.51job.com/list/000000,000000,0000,00,9,99,%2520,2,1.html?']
def parse(self, response):
"""
处理列表页数据
:param response: 下载器response对象==>中央引擎==>spider
:return:
"""
# 先拿到正确的div列表 ==> 可以使用CSS样式选择器
div_list = response.xpath('//div[@class="el"]')[4:]
for div in div_list:
item = JobItem()
item["name"] = div.xpath('./p/span/a/text()').extract_first().strip()
item["job_url"] = div.xpath('./p/span/a/@href').extract_first()
item["company_name"] = div.xpath('./span[1]/a/text()').extract_first()
item["location"] = div.xpath('./span[2]/text()').extract_first()
item["salary"] = div.xpath('./span[3]/text()').extract_first()
item["release_date"] = div.xpath('./span[4]/text()').extract_first()
yield scrapy.Request(
url=item["job_url"],
callback=self.parse_detail,
meta={"item": item},
dont_filter=True,
)
# break # 测试
yield scrapy.Request(
url=response.xpath('//a[text()="下一页"]/@href').extract_first()
)
def parse_detail(self, response):
"""
处理详情页信息
:param response: parse请求==>中央引擎==>下载器==>response对象
:return: item对象
"""
div_list = response.xpath('//div[@class="tCompany_main"]')
for div in div_list:
item = response.meta["item"]
item["job_info"] = ''.join(div.xpath('./div[1]/div[1]/p/text()').extract())
if item["job_info"] is None:
item["job_info"] = ''.join(div.xpath('./div[1]/div[1]/p/span/text()').extract().strip())
item["functional_category"] = div.xpath('./div[1]/div[1]/div[1]/p[1]/a/text()').extract_first()
if item["functional_category"] is not None:
item["functional_category"] = item["functional_category"].replace("\n", "").replace("\t", "").replace("\r", "").strip() # 替换和去除空格
item["job_keyword"] = ', '.join(div.xpath('./div[1]/div[1]/div[1]/p[2]/a/text()').extract())
item["location_work"] = div.xpath('./div[2]/div/p/text()').extract_first().strip()
item["company_info"] = div.xpath('./div[3]/div/text()').extract_first().strip()
yield item
items.py
- 这里的文件自己想写什么写什么,注意自己知道是什么就可以
- 前面讲Python的91条建议的时候也说过,把变量放到一个文件中,这俩一个目的
- 在这边定义好了之后,记得在spider.py文件中去调用
import scrapy
class JobItem(scrapy.Item):
# 定制化模型类
name = scrapy.Field() # 岗位名称
job_url = scrapy.Field() # 详情链接
company_name = scrapy.Field() # 公司名称
company_info = scrapy.Field() # 公司信息
location = scrapy.Field() # 地理位置
location_work = scrapy.Field() # 上班地址
salary = scrapy.Field() # 薪资
release_date = scrapy.Field() # 发布日期
job_keyword = scrapy.Field() # 关键字
job_info = scrapy.Field() # 职位信息
functional_category = scrapy.Field() # 职能类别
pipelines.py
- 管道,恩,怎么说呢,在settings.py文件里面有关于管道的设置
- 主要记得写过管道之后,要到settings.py中去开启管道
- 这里的管道还有一个好处,就是我们可以给个判断,让它一点一点的存
- 记住是
管道
,那不是一个一个来的?不就从上到下,一个一个走的嘛
"""
自定义管道
"""
from pprint import pprint
from pymongo import MongoClient
class JobPipeline(object):
def process_item(self, item, spider):
pprint(dict(item))
return item
class MongodbJobItemPipeline(object):
"""MongoDB管道 ==> 存储列表页数据"""
def open_spider(self, spider):
client = MongoClient(host='127.0.0.1', port=27017)
self.db = client.job
def process_item(self, item, spider):
self.db.job.insert(dict(item))
return item
settings.py
- settings.py文件真的说简单也简单,不就是改改配置嘛
- 但是说难吧,它也不好弄,就之前写的一个项目,你不设置等待时间还就不让你爬…
- 这里我把每个配置信息都写了注释,大家在看的时候,直接对着来就完事了
BOT_NAME = 'job'
SPIDER_MODULES = ['job.spiders']
NEWSPIDER_MODULE = 'job.spiders'
LOG_LEVEL="WARNING"
USER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'
# 是否遵循ROBOTS协议
ROBOTSTXT_OBEY = True
# 最大并发量
# CONCURRENT_REQUESTS = 32
# 延迟时间
# DOWNLOAD_DELAY = 3
# CONCURRENT_REQUESTS_PER_DOMAIN = 16
# CONCURRENT_REQUESTS_PER_IP = 16
# 是否关闭Cookie
# COOKIES_ENABLED = False
# Disable Telnet Console (enabled by default)
# TELNETCONSOLE_ENABLED = False
# 默认请求头
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
}
# 爬虫中间件
# SPIDER_MIDDLEWARES = {
# 'job.middlewares.JobSpiderMiddleware': 543,
# }
# 下载中间件
# DOWNLOADER_MIDDLEWARES = {
# 'job.middlewares.JobDownloaderMiddleware': 543,
# }
# 使用的扩展
# EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None,
# }
# 管道
ITEM_PIPELINES = {
'job.pipelines.JobPipeline': 300,
'job.pipelines.MongodbJobItemPipeline': 301,
}
# 用户名和密码
# AUTOTHROTTLE_ENABLED = True
# AUTOTHROTTLE_START_DELAY = 5
# AUTOTHROTTLE_MAX_DELAY = 60
# AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# AUTOTHROTTLE_DEBUG = False
# 本地缓存请求
# HTTPCACHE_ENABLED = True
# HTTPCACHE_EXPIRATION_SECS = 0
# HTTPCACHE_DIR = 'httpcache'
# HTTPCACHE_IGNORE_HTTP_CODES = []
# HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
run.py
- run.py文件只是为了运行方便
- 每次打开终端,找到文件位置,输入指令,再去run,太麻烦了,这个快多了
- 一样,这里大家项目写好了,直接复制过去就OK了,
爬虫名记得改一下
from scrapy import cmdline
cmdline.execute(['scrapy', 'crawl', '51job'])
评论区