Простая и легкая в использовании библиотека обходчика сообщений Boss (со ссылкой на github)

Python

Друг сказал вчера, что недавно хотел сменить работу. Хочешь, я помогу посмотреть, как сейчас Босс набирает сотрудников. В прошлом месяце подумал о написании фреймворка для сканера с открытым исходным кодом.kcrawler, наконец, добавивBossПоддержка класса, которая может быстро запрашивать ситуацию с набором персонала для различных должностей и отраслей по ключевым словам. Имея готовые библиотеки, помочь другу очень просто.

1. Установка

kcrawlerявляется открытым исходным кодом. Разработчики могут выбиратьcloneисходный код. Но если вы хотите избежать неприятностей, простоpip install, а затем импортируйте проект для использования.

pip install kcrawler

2. Используйте

Предусмотрено два класса.

  • Crawler: Простая настройка для сканирования любого веб-сайта.
  • Босс: Специально для Босса (рекомендуется в этой статье)

2.1 Базовый класс краулеров

kcrawlerПредоставляет базовый класс сканераCrawler, который включает в себя основные функции сканера общего назначения. Создать экземпляр веб-сайтаcrawlerобъект, затем вызовите объектcrawlметод для обхода указанных целевых данных. Поддержка html, json, сканирование изображений. Ниже приведеныBossпример конфигурации.

from kcrawler.core.Crawler import Crawler

def queryjobpage_url(x):
    p = list()
    if x[0]:
        p.append('i' + str(x[0]))
    if x[1]:
        p.append('c' + str(x[1]))
    if x[2]:
        p.append('p' + str(x[2]))
    return 'https://www.zhipin.com/{}/'.format('-'.join(p))

config = {
    'targets': {
        'city': {
            'url': 'https://www.zhipin.com/wapi/zpCommon/data/city.json',
            'method': 'get',
            'type': 'json'
        },
        'position': {
            'url': 'https://www.zhipin.com/wapi/zpCommon/data/position.json',
            'method': 'get',
            'type': 'json'
        },
        'industry': {
            'url': 'https://www.zhipin.com/wapi/zpCommon/data/oldindustry.json',
            'method': 'get',
            'type': 'json'
        },
        'conditions': {
            'url': 'https://www.zhipin.com/wapi/zpgeek/recommend/conditions.json',
            'method': 'get',
            'type': 'json'
        },
        'job': {
            'url': 'https://www.zhipin.com/wapi/zpgeek/recommend/job/list.json',
            'method': 'get',
            'type': 'json'
        },
        'queryjob': {
            'url': 'https://www.zhipin.com/job_detail/',
            'method': 'get',
            'type': 'html'
        },
        'queryjobpage': {
            'url': queryjobpage_url,
            'method': 'get',
            'type': 'html'
        },
        'jobcard': {
            'url': 'https://www.zhipin.com/wapi/zpgeek/view/job/card.json',
            'method': 'get',
            'type': 'json'
        }
    }
}

crawler = Crawler(config)

На этом создание объекта искателя завершено. Студенты, имеющие опыт работы с рептилиями, возможно, заметили, почему бы и нет.headers? На самом деле, есть два способа пройтиheaders. Один из них - настроить словарь напрямуюconfigУвеличиватьheadersключевое значение. Например:

Скопируйте все в браузереRequest Headers, присваивается переменной как строка документацииheaders.

headers = '''
:authority: www.zhipin.com
:method: GET
:path: /
....
cookie: xxx
....
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36
'''
config = {'headers': headers, 'targets': { ... }}

Второй рекомендуемый способ — создать новый файл с именемheadersдокумент. Скопируйте всеheadersСтрока перезаписывает этот файл, перезаписывает его напрямую, без добавления символьной переменной документа. когдаconfigсловарь не даетheadersполе,Crawlerавтоматически изheadersфайл прочитанheadersнить.

Выполнив вышеуказанные действия, вы можете позвонитьcrawler.crawl(target)способ обхода данных. вtargetэто словарь конфигурацииconfigсерединаtargetsопределенный ключ.

data = crawler.crawl('job')

2.2 Класс босса

использоватьCrawlerПросканированные данные — это исходные данные веб-сайта.Хотя они были преобразованы в словарь или список, для дальнейшего получения интересующих полей вам необходимо извлечь их самостоятельно. ноkcrawlerпредоставилBossКлассы можно использовать напрямую.

Конечно, рекомендуется предварительно скопировать в браузере по предыдущему способуRequest Headers, сохранить в текущий каталогheadersв файле. Тогда вы можете использовать его с удовольствиемBossКласс создает экземпляр объекта и просматривает интересующие данные.

from kcrawler import Boss

boss = Boss()

См. следующий вывод, указывающий, что чтение выполнено успешно.headersсодержимое файла.

read heades from file.
parse headers

2.2.1 Вербовочные города

cities = boss.city()

вернуть:

[{'id': 101010000,
  'name': '北京',
  'pinyin': None,
  'firstChar': 'b',
  'rank': 1,
  'children': [{'id': 101010100,
    'name': '北京',
    'pinyin': 'beijing',
    'firstChar': 'b',
    'rank': 1}]},
 {'id': 101020000,
  'name': '上海',
...
]

2.2.2 Популярные города

hotcities = boss.hotcity()

вернуть:

[{'id': 100010000, 'name': '全国'},
 {'id': 101010100, 'name': '北京'},
 {'id': 101020100, 'name': '上海'},
 {'id': 101280100, 'name': '广州'},
 {'id': 101280600, 'name': '深圳'},
 {'id': 101210100, 'name': '杭州'},
...]

2.2.3 Город, в котором в данный момент находится пользователь

user_city = boss.userCity()

вернуть:

嘿嘿,就不告诉你。。。

2.2.4 Промышленность

industries = boss.industry()

вернуть:

[{'id': 100001, 'name': '电子商务'},
 {'id': 100002, 'name': '游戏'},
 {'id': 100003, 'name': '媒体'},
 {'id': 100004, 'name': '广告营销'},
 {'id': 100005, 'name': '数据服务'},
 {'id': 100006, 'name': '医疗健康'},
 {'id': 100007, 'name': '生活服务'},
 {'id': 100008, 'name': 'O2O'},
 {'id': 100009, 'name': '旅游'},
 {'id': 100010, 'name': '分类信息'},
 {'id': 100011, 'name': '音乐/视频/阅读'},
 {'id': 100012, 'name': '在线教育'},
 {'id': 100013, 'name': '社交网络'},
...]

2.2.5 Ожидаемые позиции зарегистрированных в настоящее время пользователей (три)

expects = boss.expect()

вернуть:

[{'id': xxx, 'positionName': 'xxx'},
 {'id': xxx, 'positionName': 'xxx'},
 {'id': xxx, 'positionName': 'xxx'}]

2.4.6 Список рекомендуемых заданий для вошедших в систему пользователей

boss.job(i, page)Метод должен предоставить два параметра, первый из которыхboss.expect()Возвращает индекс списка, например, 0 представляет рекомендуемую позицию для первой желаемой позиции; второй параметрpageИспользуется для указания разбиения данных на страницы, например, 1 — первая страница.

jobs = boss.job(0, 1)

вернуть:

[{'id': 'be8bfdcdf7e99df90XV-0t-8FVo~',
  'jobName': '深度学习平台经理/技术中级',
  'salaryDesc': '30-50K',
  'jobLabels': ['深圳 福田区 购物公园', '5-10年', '本科'],
  'brandName': '中国平安',
  'brandIndustry': '互联网金融',
  'lid': '411f6b88-8a83-437a-aa5f-5de0fc4da2b7.190-GroupC,194-GroupB.1'},
 {'id': 'f649c225a1b9038f0nZ609W5E1o~',
  'jobName': '推荐系统评测工程师',
  'salaryDesc': '20-35K',
  'jobLabels': ['深圳 南山区 科技园', '1-3年', '本科'],
  'brandName': '腾讯',
  'brandIndustry': '互联网',
 {'id': '94cfec046b98b9671H150tS8E1M~',
  'jobName': '用户数据挖掘工程师',
  'salaryDesc': '20-40K·15薪',
  'jobLabels': ['深圳 南山区 南山中心', '经验不限', '本科'],
  'brandName': '今日头条',
  'brandIndustry': '移动互联网',
  'lid': '411f6b88-8a83-437a-aa5f-5de0fc4da2b7.190-GroupC,194-GroupB.4'},
...]

2.4.7 Поиск вакансий по ключевым словам

city, industry, positionполе идентификатора, соответствующее данным, которые были просканированы выше;queryИзлишне говорить о ключевых словах запроса; здесь используются два разных метода, потому чтоBossСтруктура URL первой страницы, второй страницы и последующих страниц поискового поста отличается: первая фиксированная, вторая измененная. Вот почему URL-адрес, переданный в словарь конфигурации в предыдущей статье, использует форму функции.

Поэтому, если вас интересует только запрос первой страницы использования данныхqueryjobметод; вы должны использовать методqueryjobpageметод. Конечно, на самом делеqueryjobpageМетод также может сканировать данные на первой странице, но рекомендуется использовать его отдельно, что с меньшей вероятностью сработает механизм антисканирования. В конце концов, это нормальное поведение пользователя при доступе.

tencent_jobs1 = boss.queryjob(query='腾讯', city=101280600, industry=None, position=101301)
tencent_jobs2 = boss.queryjobpage(query='腾讯', city=101280600, industry=None, position=101301, page=2)

вернуть:

[{'jobName': '天衍实验室-大数据及人工智能高级研究员',
  'salaryDesc': '30-60K',
  'jobLabels': ['深圳 南山区 科技园', '3-5年', '硕士'],
  'brandName': '腾讯',
  'brandIndustry': '互联网',
  'id': 'ce6f957a5e4cb3100nZ43dm6ElU~',
  'lid': '22Uetj173Sz.search.1'},
 {'jobName': 'QQ信息流推荐算法工程师/研究员',
  'salaryDesc': '20-40K·14薪',
  'jobLabels': ['深圳 南山区 科技园', '经验不限', '本科'],
  'brandName': '腾讯',
  'brandIndustry': '互联网',
  'id': 'a280e0b17a2aeded03Fz3dq_GFQ~',
  'lid': '22Uetj173Sz.search.2'},
...

github

GitHub.com/Ken Ratio в порядке...


Первый публичный номер этой статьи