From 6deaa846f9907d583cd0d1dd8bf7d89306e3a55c Mon Sep 17 00:00:00 2001 From: Bezleputh Date: Wed, 22 Oct 2014 18:10:32 +0200 Subject: [PATCH] [regionsjob] fix: site changed --- modules/regionsjob/browser.py | 37 +++++-- modules/regionsjob/module.py | 190 +++++++++++++++++++--------------- modules/regionsjob/pages.py | 76 +++++++------- 3 files changed, 170 insertions(+), 133 deletions(-) diff --git a/modules/regionsjob/browser.py b/modules/regionsjob/browser.py index 55b88c91..4e8e41ea 100644 --- a/modules/regionsjob/browser.py +++ b/modules/regionsjob/browser.py @@ -27,22 +27,39 @@ __all__ = ['RegionsjobBrowser'] class RegionsjobBrowser(PagesBrowser): - advert_page = URL('/offre_emploi/detailoffre.aspx\?numoffre=(?P<_id>.*)&de=consultation', AdvertPage) - search_page = URL('/offre_emploi/index.aspx\?v=___0_(?P.*)_(?P.*)_0_(?P.*)_0_0_(?P.*)_0_(?P.*)_', SearchPage) + search_page = URL('emplois/recherche.html\?.*', SearchPage) + advert_page = URL('emplois/(?P<_id>.*)\.html', AdvertPage) def __init__(self, website, *args, **kwargs): self.BASEURL = 'http://%s' % website PagesBrowser.__init__(self, *args, **kwargs) - def search_job(self, pattern='', fonction=0, secteur=0, contract=0, experience=0): - return self.search_page.go(fonction=fonction, - experience=experience, - contract=contract, - secteur=secteur, - metier=urllib.quote_plus(pattern.encode('utf-8')) - ).iter_job_adverts(domain=self.BASEURL) + def search_job(self, pattern='', fonction='', secteur='', contract='', + experience='', qualification='', enterprise_type=''): + + params = {'k': urllib.quote_plus(pattern.encode('utf-8'))} + + if fonction: + 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): 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) diff --git a/modules/regionsjob/module.py b/modules/regionsjob/module.py index b2cd7232..ca1c6b40 100644 --- a/modules/regionsjob/module.py +++ b/modules/regionsjob/module.py @@ -51,101 +51,117 @@ class RegionsjobModule(Module, CapJob): }.iteritems())]) fonction_choices = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({ - '000000': u'indifferent', - '4': u'Achat', - '20': u'Assistanat/Adm.ventes/Accueil', - '1': u'BTP - Gros Oeuvre/Second Oeuvre', - '37': u'Bureau d\'Etudes/R&D/BTP archi/conception', - '39': u'Commercial - Technico-Commercial', - '31': u'Commercial auprès des particuliers', - '30': u'Commercial auprès des professionnels', - '5': u'Commercial-Vendeur en magasin', - '6': u'Compta/Gestion/Finance/Audit', - '34': u'Direction/Resp. Co. et Centre de Profit', - '21': u'Import/Export/International', - '22': u'Informatique - Dével. Hardware', - '7': u'Informatique - Développement', - '9': u'Informatique - Systèmes d\'Information', - '10': u'Informatique - Systèmes/Réseaux', - '11': u'Ingénierie - Agro/Agri', - '12': u'Ingénierie - Chimie/Pharmacie/Bio.', - '13': u'Ingénierie - Electro-tech./Automat.', - '14': u'Ingénierie - Mécanique/Aéron.', - '15': u'Ingénierie-Telecoms/Electronique', - '44': u'Juridique/Droit', - '36': u'Logistique/Métiers du Transport ', - '16': u'Marketing/Communication/Graphisme', - '45': u'Métiers de la distribution - Management/Resp.', - '40': u'Métiers de la Fonction Publique ', - '43': u'Négociation/Gestion immobilière', - '17': u'Production - Gestion/Maintenance', - '41': u'Production - Opérateur/Manoeuvre', - '18': u'Qualité/Hygiène/Sécurité/Environnement', - '26': u'Restauration/Tourisme/Hôtellerie/Loisirs', - '19': u'RH/Personnel/Formation', - '25': u'Santé/Social', - '35': u'SAV/Hotline/Téléconseiller', - '42': u'Services à la personne/aux entreprises', + '': u'Indifferent', + 'Assistanat_admin_accueil': u'Assistanat/Adm.ventes/Accueil', + 'BTP_gros_second_oeuvre': u'BTP - Gros Oeuvre/Second Oeuvre', + 'Bureau_etude_R_D': u'Bureau d\'Etudes/R & D/BTP archi/conception', + 'Commercial_technico_com': u'Commercial - Technico-Commercial', + 'Commercial_particulier': u'Commercial auprès des particuliers', + 'Commercial_professionnel': u'Commercial auprès des professionnels', + 'Commercial_vendeur': u'Commercial-Vendeur en magasin', + 'Compta_gestion_finance_audit': u'Compta/Gestion/Finance/Audit', + 'Dir_resp_centre_profit': u'Direction/Resp. Co. et Centre de Profit', + 'Import_export_inter': u'Import/Export/International', + 'Informatique_dev_hard': u'Informatique - Dével. Hardware', + 'Informatique_dev': u'Informatique - Développement', + 'Informatique_syst_info': u'Informatique - Systèmes d\'Information', + 'Informatique_syst_reseaux': u'Informatique - Systèmes/Réseaux', + 'Ingenierie_agro_agri': u'Ingénierie - Agro/Agri', + 'Ingenierie_chimie_pharma_bio': u'Ingénierie - Chimie/Pharmacie/Bio.', + 'Ingenierie_electro_tech': u'Ingénierie - Electro-tech./Automat.', + 'Ingenierie_meca_aero': u'Ingénierie - Mécanique/Aéron.', + 'Ingenierie_telecom': u'Ingénierie - Telecoms/Electronique', + 'Juridique_droit': u'Juridique/Droit', + 'Logistique_metiers_transport': u'Logistique/Métiers du Transport', + 'Marketing_com_graphisme': u'Marketing/Communication/Graphisme', + 'Dir_management_resp': u'Métiers de la distribution - Management/Resp.', + 'Metiers_fonction_publique': u'Métiers de la Fonction Publique', + 'Negociation_gest_immo': u'Négociation/Gestion immobilière', + 'Production_gestion': u'Production - Gestion/Maintenance', + 'Production_operateur': u'Production - Opérateur/Manoeuvre', + 'Qualite_securite_environnement': u'Qualité/Hygiène/Sécurité/Environnement', + 'Restauration_hotellerie_tourisme': u'Restauration/Tourisme/Hôtellerie/Loisirs', + 'RH_Personnel_Formation': u'RH/Personnel/Formation', + 'Sante_social': u'Santé/Social', + 'SAV_Hotline': u'SAV/Hotline/Téléconseiller', + 'Services_pers_entreprises': u'Services à la personne/aux entreprises', }.iteritems())]) secteur_choices = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({ - '000000': u'indifferent', - '14': u'Agriculture/Pêche', - '9': u'Banque/Assurance/Finance', - '3': u'BTP', - '4': u'Distribution/Commerce de gros', - '17': u'Enseignement/Formation', - '15': u'Immobilier', - '18': u'Industrie Aéronautique/Aérospatial', - '2': u'Industrie Agro-alimentaire', - '5': u'Industrie Auto/Meca/Navale', - '6': u'Industrie high-tech/Telecom', - '19': u'Industrie Manufacturière', - '20': u'Industrie Pétrolière/Pétrochimie', - '21': u'Industrie Pharmaceutique/Biotechn./Chimie', - '7': u'Média/Internet/Communication', - '10': u'Restauration', - '8': u'Santé/Social/Association', - '22': u'Secteur Energie/Environnement', - '11': u'Secteur informatique/SSII', - '27': u'Service public autres', - '1': u'Service public d''etat', - '25': u'Service public des collectivités territoriales', - '26': u'Service public hospitalier', - '13': u'Services aux Entreprises', - '23': u'Services aux Personnes/Particuliers', - '24': u'Tourisme/Hôtellerie/Loisirs', - '16': u'Transport/Logistique', + '': u'Indifferent', + 'Agri_peche': u'Agriculture/Pêche', + 'Banq_assur_finan': u'Banque/Assurance/Finance', + 'BTP': u'BTP', + 'Distrib_commerce': u'Distribution/Commerce de gros', + 'Enseign_forma': u'Enseignement/Formation', + 'Immo': u'Immobilier', + 'Ind_aero': u'Industrie Aéronautique/Aérospatial', + 'Ind_agro': u'Industrie Agro-alimentaire', + 'Ind_auto_meca_nav': u'Industrie Auto/Meca/Navale', + 'Ind_hightech_telecom': u'Industrie high-tech/Telecom', + 'Ind_manufact': u'Industrie Manufacturière', + 'Ind_petro': u'Industrie Pétrolière/Pétrochimie', + 'Ind_pharma_bio_chim': u'Industrie Pharmaceutique/Biotechn./Chimie', + 'Media_internet_com': u'Média/Internet/Communication', + 'Resto': u'Restauration', + 'Sante_social': u'Santé/Social/Association', + 'Energie_envir': u'Secteur Energie/Environnement', + 'Inform_SSII': u'Secteur informatique/SSII', + 'Serv_public_autre': u'Service public autres', + 'Serv_public_collec_terri': u'Service public des collectivités territoriales', + 'Serv_public_etat': u'Service public d\'état', + 'Serv_public_hosp': u'Service public hospitalier', + 'Serv_entreprise': u'Services aux Entreprises', + 'Serv_pers_part': u'Services aux Personnes/Particuliers', + 'Tourism_hotel_loisir': u'Tourisme/Hôtellerie/Loisirs', + 'Transport_logist': u'Transport/Logistique', }.iteritems())]) experience_choices = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({ - '000000': u'Indifférent', - '7': u'BEP/CAP', - '4': u'Employé/Opérateur/Ouvrier Spe/Bac', - '3': u'Technicien/Employé Bac +2', - '6': u'Agent de maîtrise/Bac +3/4', - '2': u'Ingénieur/Cadre/Bac +5', - '1': u'Cadre dirigeant', + ' ': u'Indifferent', + 'Inf_1': u'- 1 an', + '1_7': u'1 à 7 ans', + 'Sup_7': u'+ 7 ans', }.iteritems())]) contract_choices = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({ - '000000': u'Indifférent', - '6': u'Alternance', - '1': u'CDD', - '2': u'CDI', - '8': u'Franchise', - '7': u'Indépendant', - '3': u'Stage', - '4': u'Travail temporaire', + '': u'Tous types de contrat', + 'CDD': u'CDD', + 'CDI': u'CDI', + 'Stage': u'Stage', + 'Travail_temp': u'Travail temporaire', + 'Alternance': u'Alternance', + 'Independant': u'Indépendant', + '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())]) CONFIG = BackendConfig(Value('website', label=u'Region', choices=website_choices), Value('metier', label='Job name', masked=False, default=''), - Value('fonction', label=u'Fonction', choices=fonction_choices, default='000000'), - Value('secteur', label=u'Secteur', choices=secteur_choices, default='000000'), - Value('contract', label=u'Contract', choices=contract_choices, default='000000'), - Value('experience', label=u'Experience', choices=experience_choices, default='000000'), - ) + Value('fonction', label=u'Fonction', choices=fonction_choices, default=''), + Value('secteur', label=u'Secteur', choices=secteur_choices, default=''), + Value('contract', label=u'Contract', choices=contract_choices, default=''), + 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): return self.create_browser(self.config['website'].get()) @@ -155,10 +171,12 @@ class RegionsjobModule(Module, CapJob): def advanced_search_job(self): return self.browser.search_job(pattern=self.config['metier'].get(), - fonction=int(self.config['fonction'].get()), - secteur=int(self.config['secteur'].get()), - contract=int(self.config['contract'].get()), - experience=int(self.config['experience'].get())) + fonction=self.config['fonction'].get(), + secteur=self.config['secteur'].get(), + contract=self.config['contract'].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): return self.browser.get_job_advert(_id, advert) diff --git a/modules/regionsjob/pages.py b/modules/regionsjob/pages.py index d4eda18b..74e9943a 100644 --- a/modules/regionsjob/pages.py +++ b/modules/regionsjob/pages.py @@ -17,30 +17,45 @@ # You should have received a copy of the GNU Affero General Public License # along with weboob. If not, see . -from weboob.browser.pages import HTMLPage -from weboob.browser.elements import ItemElement, SkipItem, ListElement, method -from weboob.browser.filters.standard import CleanText, Regexp, Format, Env, DateGuesser, DateTime -from weboob.browser.filters.html import Link, CleanHTML -from weboob.tools.date import LinearDateGuesser +from weboob.browser.pages import HTMLPage, pagination +from weboob.browser.elements import ItemElement, ListElement, method +from weboob.browser.filters.standard import CleanText, Regexp, Format, Env, Date, BrowserURL, Join +from weboob.browser.filters.html import CleanHTML, Link from weboob.capabilities.job import BaseJobAdvert +from weboob.exceptions import ParseError +from datetime import date, timedelta class SearchPage(HTMLPage): + @pagination @method 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): klass = BaseJobAdvert obj_id = Format(u'%s#%s', - Env('domain'), - Regexp(Link('div/span[@class="offres_poste"]/a'), '.*?numoffre=(.*?)&de=consultation')) - obj_title = CleanText('div/span[@class="offres_poste"]/a') - obj_society_name = CleanText('div/span[@class="offres_entreprise"]/span/a') - obj_place = CleanText('div/span[@class="offres_ville"]/span/span/span') - obj_contract_type = CleanText('div/span[@class="offres_poste"]/span') - obj_publication_date = DateGuesser(CleanText('div/span[@class="offres_date"]'), LinearDateGuesser()) + Regexp(Env('domain'), 'http://www\.(.*)\.com'), + Regexp(CleanText('h1/a[2]/@href'), '/emplois/(.*)\.html')) + obj_title = CleanText('h1/a[2]') + obj_society_name = CleanText('figure/span[@itemprop="name"]') + obj_place = CleanText('p[@class="inlineblock max-width-75"]') + obj_contract_type = CleanText('p[@class="max-width-75"]') + + 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): @@ -48,28 +63,15 @@ class AdvertPage(HTMLPage): class get_job_advert(ItemElement): klass = BaseJobAdvert - def parse(self, el): - 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_description = Join('\n%s', '//div[@id="annonce-detail"]/p[@class="text"]', textCleaner=CleanHTML) obj_id = Env('_id') - obj_url = Env('url') - obj_publication_date = DateTime(Regexp(CleanText('//div[@id="annonce"]/p[@class="date_ref"]'), - '(\d{2}/\d{2}/\d{4})')) - obj_title = CleanText('//div[@id="annonce"]/h1') - obj_society_name = CleanText('//div[@id="annonce"]/p[@class="contrat_loc"]/strong[1]') - 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_pay = CleanText('//div[@id="annonce"]/p[@class="rubrique_annonce"]/following-sibling::p[1]') + obj_url = BrowserURL('advert_page', _id=Env('_id')) + obj_publication_date = Date(Regexp(CleanText('//div[@id="annonce-detail"]/p[@class="infos"]'), + '(\d{2}/\d{2}/\d{4})')) + obj_title = CleanText('//div[@id="annonce"]/div/div/h1') + obj_society_name = CleanText('//section[@class="entp-resume"]/h1/a') + + obj_contract_type = CleanText('//dl[@class="infos-annonce"]/dt[span[@class="picto picto-contrat-grey"]]/following-sibling::dd[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 : ', '')])