" name="sm-site-verification"/>
侧边栏壁纸
博主头像
PySuper博主等级

千里之行,始于足下

  • 累计撰写 203 篇文章
  • 累计创建 14 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

爬虫框架 Scrapy 实战(一)

PySuper
2019-11-03 / 0 评论 / 0 点赞 / 28 阅读 / 7847 字
温馨提示:
所有牛逼的人都有一段苦逼的岁月。 但是你只要像SB一样去坚持,终将牛逼!!! ✊✊✊

创建项目之类的,这里就不说了,直接丢代码了。

什么???你说你不会创建项目,不会整虚拟环境!前面章节有,先看基础!

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'])
0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区