Друг сказал вчера, что недавно хотел сменить работу. Хочешь, я помогу посмотреть, как сейчас Босс набирает сотрудников. В прошлом месяце подумал о написании фреймворка для сканера с открытым исходным кодом.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 в порядке...
Первый публичный номер этой статьи