<jupyter_start><jupyter_text>Stellenausschreibung im Ausland (Viajob.ro) Der Bundesrat setzt die Masseneinwanderungsinitiative in Etappen um. Seit dem 1.Juni 2018 gilt in der Schweiz die Stellenmeldepflicht. Sie wird in einem ersten Schritt in denjenigen Berufsarten eingeführt, in denen die gesamtschweizerische Arbeitslosenquote 8 Prozent erreicht oder überschreitet. Per 1. Januar 2020 wird dieser Schwellenwert auf 5 Prozent gesenkt. Trotz dem Ja zur Masseneinwanderungsinitiative schreiben Schweizer Firmen Jobs in EU-Ländern aus, zum Teil zu Dumpinglöhnen. Auf dem rumänischen Portal Viajob wird etwa ein Veterinär in Zürich gesucht für einen Lohn von 4000 CHF pro Monat. Mich interessiert in welchen Ländern, auf welchen Protalen, werden welche Jobs in der Schweiz, von wem und zu welchem Lohn ausgeschrieben. Quelle: https://www.viajob.ro/   Ziel: Eine Tabelle mit allen Ausschreibungen für eine Stelle in der Schweiz. Zu jeder ausgeschriebenen Stelle soll der Beruf, Ort und Monatsgehalt angegeben werden.   Schritt 1: Import der Libraries<jupyter_code>import requests
from bs4 import BeautifulSoup
import pandas as pd<jupyter_output><empty_output><jupyter_text>Schritt 2: Webseite analysieren Die Stellenangebote für die Schweiz erscheinen auf einer Unterseite. Schweiz auf rumänisch heisst "Elvetia". Alle gesuchten Informationen (Beruf, Ort, Gehalt) sind bereits dort verfügbar.  https://www.viajob.ro/munca-strainatate?tara=Elvetia  Zusätzliche Informationen gibt es pro Stellengesuch auf einer Unterwebseite. Die Url setzt sich in der Regel aus der Jobbezeichnung und Ort zusammen:https://www.viajob.ro/locuri-de-munca-operator-cnc-geneva.html<jupyter_code>url = 'https://www.viajob.ro/munca-strainatate?tara=Elvetia'
content = requests.get(url).text 
soup = BeautifulSoup(content, 'html.parser')
# soup
# Ort und Beruf auslesen

# 3 Varianten
# location_job = soup.select('h2.h2blockhome')
# location_job = soup.find_all('h2', class_='h2blockhome')
location_job = soup.find_all('h2', {'class':'h2blockhome'})
location_job[1]
location_job[1].text<jupyter_output><empty_output><jupyter_text>**TIPP:** Webseite analysieren mit SelectorGadget. ACHTUNG funktioniert nur in Google Chrome! **FRAGE:** Gibt es eine Möglichkeiten bereits hier Beruf und Job hier zu trennen und als separate Listen auszulesen? **JA!** Beruf und Ort werden durch \n voneinander getrennt und lässt sich dort splitten. Siehe unter Schritt 3 die verschiedenen Varianten wie das zB im For-Loop genutzt werden kann!<jupyter_code>len(location_job)
salery = soup.find_all('strong', {'class':'salarluna'})
salery[1]
salery[1].text
len(salery)
# BESSER: den ganzen Block auslesen
# ad = soup.select('div.blockprincipal')
ad = soup.find_all('div', class_="blockprincipal")
ad[0]
ad[1]
ad[1].text<jupyter_output><empty_output><jupyter_text>**ACHTUNG:** Es gibt ein Problem. In diesem Block sind die h2 und strong nicht enthalten.HTML-Code der ganzen Webseite https://www.viajob.ro/munca-strainatate?tara=Elvetia als txt-File den Output von soup abspeichern mittels Edit > Copy Cells > Copy Paste in html.txt**GRUND:** Infos im Block wird nachgeladen mit Java-Script. Deshalb erscheint der Block leer. Wenn man mit Beautifulsoup das holen will ist es leer. Auf die Spitze getrieben wird das zB von Facebook.**ABER** warum funktioniert es wenn ich eine Liste bauen für Ort, Beruf und Monatslohn? Könnte es zb oben auch mehrere blockprincipal-Blöcke geben? Analyse HTML-Code zeigt: die einzigen blockprincipal vorher sind im Stylguide drin.<jupyter_code># HTML-Code abspeichern

html_code = content    # Variable content wurde ganz am Anfang definiert 
 
with open('html_code_viajob.txt', 'w') as file:   
    file.write(html_code)    
    file.close()
#Variante 2, um HTML abzuspeichern

#with open(“output1.html”, “w”) as file:
   #file.write(str(soup))<jupyter_output><empty_output><jupyter_text>Schritt 3: For-Loop Es braucht einen Work around. Zum Glück sind alle Listen gleich lang, und die einzelnen Elemente korrepsondieren miteinander. Neue Liste bauen<jupyter_code># VARIANTE 1

lst = []
for description,chf in zip(location_job,salery):
    gesplittet = description.text.split('\n')
    mini_dict = {"Beruf": gesplittet[0],
                'Ort':gesplittet[1],
                 'Monatslohn':chf.text}
    
    lst.append(mini_dict)
#lst
# VARIANTE 2

lst = []
for description,chf in zip(location_job,salery):
    beruf, ort  = description.text.split('\n')
    mini_dict = {"Beruf": beruf,
                'Ort':ort,
                 'Monatslohn':chf.text}
    
    lst.append(mini_dict)
#lst
# VARIANTE 3

output = soup.find_all('h2', {'class':'h2blockhome'})
output2 = soup.find_all('strong', {'class':'salarluna'})

job = [item.text.split('\n')[0] for item in output]
location = [item.text.split('\n')[1] for item in output]
salary = [item.text for item in output2]

data = list(zip(job, location,salary))
df = pd.DataFrame.from_records(data,columns=["job","loc","salary"])
df.head(4)<jupyter_output><empty_output><jupyter_text>Schritt 4: Daten mit Pandas analysieren<jupyter_code>df = pd.DataFrame(lst)
df.to_csv('list_open_positions_viajob.csv')
df.head(3)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09839551517494684, 'fraction_numerical': 0.010052194084670405, 'mean_word_length': 5.348466257668711, 'pattern_counts': {'":': 2, '<': 25, '<?xml version=': 0, '>': 27, 'https://': 5, 'lorem ipsum': 0, 'www.': 5, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '646945', 'license': 'MIT', 'n_tokens_mistral': 1830, 'n_tokens_neox': 1826, 'n_words': 520, 'path': 'Jobportale/CODE_Stellenausschreibungen_im_Ausland_Viajob_V1.2.ipynb', 'repo_name': 'Clav1ta/GitHub', 'size': '5173'}