[regionsjob] fix: site changed

This commit is contained in:
Bezleputh 2014-10-22 18:10:32 +02:00
commit 6deaa846f9
3 changed files with 170 additions and 133 deletions

View file

@ -27,22 +27,39 @@ __all__ = ['RegionsjobBrowser']
class RegionsjobBrowser(PagesBrowser): class RegionsjobBrowser(PagesBrowser):
advert_page = URL('/offre_emploi/detailoffre.aspx\?numoffre=(?P<_id>.*)&de=consultation', AdvertPage) search_page = URL('emplois/recherche.html\?.*', SearchPage)
search_page = URL('/offre_emploi/index.aspx\?v=___0_(?P<fonction>.*)_(?P<experience>.*)_0_(?P<contract>.*)_0_0_(?P<secteur>.*)_0_(?P<metier>.*)_', SearchPage) advert_page = URL('emplois/(?P<_id>.*)\.html', AdvertPage)
def __init__(self, website, *args, **kwargs): def __init__(self, website, *args, **kwargs):
self.BASEURL = 'http://%s' % website self.BASEURL = 'http://%s' % website
PagesBrowser.__init__(self, *args, **kwargs) PagesBrowser.__init__(self, *args, **kwargs)
def search_job(self, pattern='', fonction=0, secteur=0, contract=0, experience=0): def search_job(self, pattern='', fonction='', secteur='', contract='',
return self.search_page.go(fonction=fonction, experience='', qualification='', enterprise_type=''):
experience=experience,
contract=contract, params = {'k': urllib.quote_plus(pattern.encode('utf-8'))}
secteur=secteur,
metier=urllib.quote_plus(pattern.encode('utf-8')) if fonction:
).iter_job_adverts(domain=self.BASEURL) params['f'] = fonction
if qualification:
params['q'] = qualification
if contract:
params['c'] = contract
if experience:
params['e'] = experience
if secteur:
params['s'] = secteur
if enterprise_type:
params['et'] = enterprise_type
return self.search_page.go(params=params).iter_job_adverts(domain=self.BASEURL)
def get_job_advert(self, _id, advert): def get_job_advert(self, _id, advert):
splitted_id = _id.split('#') splitted_id = _id.split('#')
self.BASEURL = splitted_id[0] self.BASEURL = 'http://www.%s.com' % splitted_id[0]
return self.advert_page.go(_id=splitted_id[1]).get_job_advert(obj=advert) return self.advert_page.go(_id=splitted_id[1]).get_job_advert(obj=advert)

View file

@ -51,101 +51,117 @@ class RegionsjobModule(Module, CapJob):
}.iteritems())]) }.iteritems())])
fonction_choices = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({ fonction_choices = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({
'000000': u'indifferent', '': u'Indifferent',
'4': u'Achat', 'Assistanat_admin_accueil': u'Assistanat/Adm.ventes/Accueil',
'20': u'Assistanat/Adm.ventes/Accueil', 'BTP_gros_second_oeuvre': u'BTP - Gros Oeuvre/Second Oeuvre',
'1': u'BTP - Gros Oeuvre/Second Oeuvre', 'Bureau_etude_R_D': u'Bureau d\'Etudes/R & D/BTP archi/conception',
'37': u'Bureau d\'Etudes/R&amp;D/BTP archi/conception', 'Commercial_technico_com': u'Commercial - Technico-Commercial',
'39': u'Commercial - Technico-Commercial', 'Commercial_particulier': u'Commercial auprès des particuliers',
'31': u'Commercial auprès des particuliers', 'Commercial_professionnel': u'Commercial auprès des professionnels',
'30': u'Commercial auprès des professionnels', 'Commercial_vendeur': u'Commercial-Vendeur en magasin',
'5': u'Commercial-Vendeur en magasin', 'Compta_gestion_finance_audit': u'Compta/Gestion/Finance/Audit',
'6': u'Compta/Gestion/Finance/Audit', 'Dir_resp_centre_profit': u'Direction/Resp. Co. et Centre de Profit',
'34': u'Direction/Resp. Co. et Centre de Profit', 'Import_export_inter': u'Import/Export/International',
'21': u'Import/Export/International', 'Informatique_dev_hard': u'Informatique - Dével. Hardware',
'22': u'Informatique - Dével. Hardware', 'Informatique_dev': u'Informatique - Développement',
'7': u'Informatique - Développement', 'Informatique_syst_info': u'Informatique - Systèmes d\'Information',
'9': u'Informatique - Systèmes d\'Information', 'Informatique_syst_reseaux': u'Informatique - Systèmes/Réseaux',
'10': u'Informatique - Systèmes/Réseaux', 'Ingenierie_agro_agri': u'Ingénierie - Agro/Agri',
'11': u'Ingénierie - Agro/Agri', 'Ingenierie_chimie_pharma_bio': u'Ingénierie - Chimie/Pharmacie/Bio.',
'12': u'Ingénierie - Chimie/Pharmacie/Bio.', 'Ingenierie_electro_tech': u'Ingénierie - Electro-tech./Automat.',
'13': u'Ingénierie - Electro-tech./Automat.', 'Ingenierie_meca_aero': u'Ingénierie - Mécanique/Aéron.',
'14': u'Ingénierie - Mécanique/Aéron.', 'Ingenierie_telecom': u'Ingénierie - Telecoms/Electronique',
'15': u'Ingénierie-Telecoms/Electronique', 'Juridique_droit': u'Juridique/Droit',
'44': u'Juridique/Droit', 'Logistique_metiers_transport': u'Logistique/Métiers du Transport',
'36': u'Logistique/Métiers du Transport ', 'Marketing_com_graphisme': u'Marketing/Communication/Graphisme',
'16': u'Marketing/Communication/Graphisme', 'Dir_management_resp': u'Métiers de la distribution - Management/Resp.',
'45': u'Métiers de la distribution - Management/Resp.', 'Metiers_fonction_publique': u'Métiers de la Fonction Publique',
'40': u'Métiers de la Fonction Publique ', 'Negociation_gest_immo': u'Négociation/Gestion immobilière',
'43': u'Négociation/Gestion immobilière', 'Production_gestion': u'Production - Gestion/Maintenance',
'17': u'Production - Gestion/Maintenance', 'Production_operateur': u'Production - Opérateur/Manoeuvre',
'41': u'Production - Opérateur/Manoeuvre', 'Qualite_securite_environnement': u'Qualité/Hygiène/Sécurité/Environnement',
'18': u'Qualité/Hygiène/Sécurité/Environnement', 'Restauration_hotellerie_tourisme': u'Restauration/Tourisme/Hôtellerie/Loisirs',
'26': u'Restauration/Tourisme/Hôtellerie/Loisirs', 'RH_Personnel_Formation': u'RH/Personnel/Formation',
'19': u'RH/Personnel/Formation', 'Sante_social': u'Santé/Social',
'25': u'Santé/Social', 'SAV_Hotline': u'SAV/Hotline/Téléconseiller',
'35': u'SAV/Hotline/Téléconseiller', 'Services_pers_entreprises': u'Services à la personne/aux entreprises',
'42': u'Services à la personne/aux entreprises',
}.iteritems())]) }.iteritems())])
secteur_choices = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({ secteur_choices = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({
'000000': u'indifferent', '': u'Indifferent',
'14': u'Agriculture/Pêche', 'Agri_peche': u'Agriculture/Pêche',
'9': u'Banque/Assurance/Finance', 'Banq_assur_finan': u'Banque/Assurance/Finance',
'3': u'BTP', 'BTP': u'BTP',
'4': u'Distribution/Commerce de gros', 'Distrib_commerce': u'Distribution/Commerce de gros',
'17': u'Enseignement/Formation', 'Enseign_forma': u'Enseignement/Formation',
'15': u'Immobilier', 'Immo': u'Immobilier',
'18': u'Industrie Aéronautique/Aérospatial', 'Ind_aero': u'Industrie Aéronautique/Aérospatial',
'2': u'Industrie Agro-alimentaire', 'Ind_agro': u'Industrie Agro-alimentaire',
'5': u'Industrie Auto/Meca/Navale', 'Ind_auto_meca_nav': u'Industrie Auto/Meca/Navale',
'6': u'Industrie high-tech/Telecom', 'Ind_hightech_telecom': u'Industrie high-tech/Telecom',
'19': u'Industrie Manufacturière', 'Ind_manufact': u'Industrie Manufacturière',
'20': u'Industrie Pétrolière/Pétrochimie', 'Ind_petro': u'Industrie Pétrolière/Pétrochimie',
'21': u'Industrie Pharmaceutique/Biotechn./Chimie', 'Ind_pharma_bio_chim': u'Industrie Pharmaceutique/Biotechn./Chimie',
'7': u'Média/Internet/Communication', 'Media_internet_com': u'Média/Internet/Communication',
'10': u'Restauration', 'Resto': u'Restauration',
'8': u'Santé/Social/Association', 'Sante_social': u'Santé/Social/Association',
'22': u'Secteur Energie/Environnement', 'Energie_envir': u'Secteur Energie/Environnement',
'11': u'Secteur informatique/SSII', 'Inform_SSII': u'Secteur informatique/SSII',
'27': u'Service public autres', 'Serv_public_autre': u'Service public autres',
'1': u'Service public d''etat', 'Serv_public_collec_terri': u'Service public des collectivités territoriales',
'25': u'Service public des collectivités territoriales', 'Serv_public_etat': u'Service public d\'état',
'26': u'Service public hospitalier', 'Serv_public_hosp': u'Service public hospitalier',
'13': u'Services aux Entreprises', 'Serv_entreprise': u'Services aux Entreprises',
'23': u'Services aux Personnes/Particuliers', 'Serv_pers_part': u'Services aux Personnes/Particuliers',
'24': u'Tourisme/Hôtellerie/Loisirs', 'Tourism_hotel_loisir': u'Tourisme/Hôtellerie/Loisirs',
'16': u'Transport/Logistique', 'Transport_logist': u'Transport/Logistique',
}.iteritems())]) }.iteritems())])
experience_choices = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({ experience_choices = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({
'000000': u'Indifférent', ' ': u'Indifferent',
'7': u'BEP/CAP', 'Inf_1': u'- 1 an',
'4': u'Employé/Opérateur/Ouvrier Spe/Bac', '1_7': u'1 à 7 ans',
'3': u'Technicien/Employé Bac +2', 'Sup_7': u'+ 7 ans',
'6': u'Agent de maîtrise/Bac +3/4',
'2': u'Ingénieur/Cadre/Bac +5',
'1': u'Cadre dirigeant',
}.iteritems())]) }.iteritems())])
contract_choices = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({ contract_choices = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({
'000000': u'Indifférent', '': u'Tous types de contrat',
'6': u'Alternance', 'CDD': u'CDD',
'1': u'CDD', 'CDI': u'CDI',
'2': u'CDI', 'Stage': u'Stage',
'8': u'Franchise', 'Travail_temp': u'Travail temporaire',
'7': u'Indépendant', 'Alternance': u'Alternance',
'3': u'Stage', 'Independant': u'Indépendant',
'4': u'Travail temporaire', 'Franchise': u'Franchise',
}.iteritems())])
qualification_choice = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({
'': u'Indifferent',
'BEP_CAP': u'BEP/CAP',
'Employe_Operateur': u'Employé/Opérateur/Ouvrier Spe/Bac',
'Technicien_B2': u'Technicien/Employé Bac +2',
'Agent_maitrise_B3': u'Agent de maîtrise/Bac +3/4',
'Ingenieur_B5': u'Ingénieur/Cadre/Bac +5',
'Cadre_dirigeant': u'> Bac + 5 (cadre dirigeant)',
}.iteritems())])
enterprise_type_choice = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({
'': u'Tous types d\'entreprises',
'Cabinet_recr': u'Cabinets de recrutement',
'Entreprises': u'Entreprises',
'SSII': u'SSII',
'Travail_temporaire': u'Travail temporaire',
}.iteritems())]) }.iteritems())])
CONFIG = BackendConfig(Value('website', label=u'Region', choices=website_choices), CONFIG = BackendConfig(Value('website', label=u'Region', choices=website_choices),
Value('metier', label='Job name', masked=False, default=''), Value('metier', label='Job name', masked=False, default=''),
Value('fonction', label=u'Fonction', choices=fonction_choices, default='000000'), Value('fonction', label=u'Fonction', choices=fonction_choices, default=''),
Value('secteur', label=u'Secteur', choices=secteur_choices, default='000000'), Value('secteur', label=u'Secteur', choices=secteur_choices, default=''),
Value('contract', label=u'Contract', choices=contract_choices, default='000000'), Value('contract', label=u'Contract', choices=contract_choices, default=''),
Value('experience', label=u'Experience', choices=experience_choices, default='000000'), Value('experience', label=u'Experience', choices=experience_choices, default=''),
) Value('qualification', label=u'Qualification', choices=qualification_choice, default=''),
Value('enterprise_type', label=u'Enterprise type',
choices=enterprise_type_choice, default=''))
def create_default_browser(self): def create_default_browser(self):
return self.create_browser(self.config['website'].get()) return self.create_browser(self.config['website'].get())
@ -155,10 +171,12 @@ class RegionsjobModule(Module, CapJob):
def advanced_search_job(self): def advanced_search_job(self):
return self.browser.search_job(pattern=self.config['metier'].get(), return self.browser.search_job(pattern=self.config['metier'].get(),
fonction=int(self.config['fonction'].get()), fonction=self.config['fonction'].get(),
secteur=int(self.config['secteur'].get()), secteur=self.config['secteur'].get(),
contract=int(self.config['contract'].get()), contract=self.config['contract'].get(),
experience=int(self.config['experience'].get())) experience=self.config['experience'].get().strip(),
qualification=self.config['qualification'].get(),
enterprise_type=self.config['enterprise_type'].get())
def get_job_advert(self, _id, advert=None): def get_job_advert(self, _id, advert=None):
return self.browser.get_job_advert(_id, advert) return self.browser.get_job_advert(_id, advert)

View file

@ -17,30 +17,45 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>. # along with weboob. If not, see <http://www.gnu.org/licenses/>.
from weboob.browser.pages import HTMLPage from weboob.browser.pages import HTMLPage, pagination
from weboob.browser.elements import ItemElement, SkipItem, ListElement, method from weboob.browser.elements import ItemElement, ListElement, method
from weboob.browser.filters.standard import CleanText, Regexp, Format, Env, DateGuesser, DateTime from weboob.browser.filters.standard import CleanText, Regexp, Format, Env, Date, BrowserURL, Join
from weboob.browser.filters.html import Link, CleanHTML from weboob.browser.filters.html import CleanHTML, Link
from weboob.tools.date import LinearDateGuesser
from weboob.capabilities.job import BaseJobAdvert from weboob.capabilities.job import BaseJobAdvert
from weboob.exceptions import ParseError
from datetime import date, timedelta
class SearchPage(HTMLPage): class SearchPage(HTMLPage):
@pagination
@method @method
class iter_job_adverts(ListElement): class iter_job_adverts(ListElement):
item_xpath = '//div[@id="liste_offres"]/ul/li' item_xpath = '//section[@class="annonce"]'
def next_page(self):
return Link('//a[@class="picto picto-nextsmall"]')(self)
class item(ItemElement): class item(ItemElement):
klass = BaseJobAdvert klass = BaseJobAdvert
obj_id = Format(u'%s#%s', obj_id = Format(u'%s#%s',
Env('domain'), Regexp(Env('domain'), 'http://www\.(.*)\.com'),
Regexp(Link('div/span[@class="offres_poste"]/a'), '.*?numoffre=(.*?)&de=consultation')) Regexp(CleanText('h1/a[2]/@href'), '/emplois/(.*)\.html'))
obj_title = CleanText('div/span[@class="offres_poste"]/a') obj_title = CleanText('h1/a[2]')
obj_society_name = CleanText('div/span[@class="offres_entreprise"]/span/a') obj_society_name = CleanText('figure/span[@itemprop="name"]')
obj_place = CleanText('div/span[@class="offres_ville"]/span/span/span') obj_place = CleanText('p[@class="inlineblock max-width-75"]')
obj_contract_type = CleanText('div/span[@class="offres_poste"]/span') obj_contract_type = CleanText('p[@class="max-width-75"]')
obj_publication_date = DateGuesser(CleanText('div/span[@class="offres_date"]'), LinearDateGuesser())
def obj_publication_date(self):
_date = CleanText('p[@class="infos"]')
try:
return Date(_date)(self)
except ParseError:
str_date = _date(self)
if 'hier' in str_date:
return date.today() - timedelta(days=1)
else:
return date.today()
class AdvertPage(HTMLPage): class AdvertPage(HTMLPage):
@ -48,28 +63,15 @@ class AdvertPage(HTMLPage):
class get_job_advert(ItemElement): class get_job_advert(ItemElement):
klass = BaseJobAdvert klass = BaseJobAdvert
def parse(self, el): obj_description = Join('\n%s', '//div[@id="annonce-detail"]/p[@class="text"]', textCleaner=CleanHTML)
if self.obj.id:
advert = self.obj
advert.url = self.page.url
advert.description = Format(u'%s\r\n%s',
CleanHTML('//div[@id="annonce"]/p[@id="description_annonce"]'),
CleanHTML('//div[@id="annonce"]/p[@id="description_annonce"]/following-sibling::p[1]'))(el)
advert.pay = CleanText('//div[@id="annonce"]/p[@class="rubrique_annonce"]/following-sibling::p[1]')(el)
raise SkipItem()
self.env['url'] = self.page.url
obj_description = Format(u'%s%s',
CleanHTML('//div[@id="annonce"]/p[@id="description_annonce"]'),
CleanHTML('//div[@id="annonce"]/p[@id="description_annonce"]/following-sibling::p[1]'))
obj_id = Env('_id') obj_id = Env('_id')
obj_url = Env('url') obj_url = BrowserURL('advert_page', _id=Env('_id'))
obj_publication_date = DateTime(Regexp(CleanText('//div[@id="annonce"]/p[@class="date_ref"]'), obj_publication_date = Date(Regexp(CleanText('//div[@id="annonce-detail"]/p[@class="infos"]'),
'(\d{2}/\d{2}/\d{4})')) '(\d{2}/\d{2}/\d{4})'))
obj_title = CleanText('//div[@id="annonce"]/h1') obj_title = CleanText('//div[@id="annonce"]/div/div/h1')
obj_society_name = CleanText('//div[@id="annonce"]/p[@class="contrat_loc"]/strong[1]') obj_society_name = CleanText('//section[@class="entp-resume"]/h1/a')
obj_contract_type = CleanText('//div[@id="annonce"]/p[@class="contrat_loc"]/strong[2]')
obj_place = CleanText('//div[@id="annonce"]/p[@class="contrat_loc"]/strong[3]') obj_contract_type = CleanText('//dl[@class="infos-annonce"]/dt[span[@class="picto picto-contrat-grey"]]/following-sibling::dd[1]')
obj_pay = CleanText('//div[@id="annonce"]/p[@class="rubrique_annonce"]/following-sibling::p[1]') obj_place = CleanText('//dl[@class="infos-annonce"]/dt[span[@class="picto picto-geolocalisation-grey"]]/following-sibling::dd[1]')
obj_pay = CleanText('//div[@id="annonce-detail"]/p[@class="infos"]/preceding-sibling::p[1]',
replace=[('Salaire : ', '')])