使用Python无法使用不变的网址抓取多个页面

时间:2018-07-05 03:01:24

标签: python python-3.x web-scraping beautifulsoup

在寻找提示后,我发现我的问题与this question密切相关,并且基于this answer我以为我要解决我的问题,但是我没有解决。

我需要从该网站http://elempleo.com/cr/ofertas-empleo提取所有URL,我做了以下工作:

page_no=1
payload = {"jobOfferId":0,
           "salaryInfo":[],
           "city":0,
           "publishDate":0,
           "area":40,
           "countryId":0,
           "departmentId":0,
           "companyId":0,
           "pageIndex":page_no,
           "pageSize":"20"},
           "sortExpression":"PublishDate_Desc"}

page = requests.get('http://elempleo.com/cr/ofertas-empleo/get', params=payload)
soup = BeautifulSoup(page.content, 'html.parser')

href_list=soup.select(".text-ellipsis")

for urls in href_list:
    print("http://elempleo.com"+urls.get("href"))

http://elempleo.com/cr/ofertas-trabajo/ap-representative/757190
http://elempleo.com/cr/ofertas-trabajo/ingeniero-de-procesos-sap/757189
http://elempleo.com/cr/ofertas-trabajo/sr-program-analyst-months/757188
http://elempleo.com/cr/ofertas-trabajo/executive-asistant/757187
http://elempleo.com/cr/ofertas-trabajo/asistente-comercial-bilingue/757186
http://elempleo.com/cr/ofertas-trabajo/accounting-assistant/757185
http://elempleo.com/cr/ofertas-trabajo/asistente-contable/757184
http://elempleo.com/cr/ofertas-trabajo/personal-para-cajas-alajuela-con-experiencia-en-farmacia/757183
http://elempleo.com/cr/ofertas-trabajo/oficial-de-seguridad/743703
http://elempleo.com/cr/ofertas-trabajo/tecnico-de-mantenimiento-en-extrusion/757182
http://elempleo.com/cr/ofertas-trabajo/gerente-servicio-al-cliente-y-ventas/757181
http://elempleo.com/cr/ofertas-trabajo/encargadoa-departamento-de-recursos-humanos-ingles-intermedio/757180
http://elempleo.com/cr/ofertas-trabajo/director-of-development/757177
http://elempleo.com/cr/ofertas-trabajo/generalista-de-recursos-humanos-ingles-intermedio/757178
http://elempleo.com/cr/ofertas-trabajo/accounts-payable-specialist-seasonal-contract/757176
http://elempleo.com/cr/ofertas-trabajo/electricista-industrial/757175
http://elempleo.com/cr/ofertas-trabajo/payroll-analyst-months-contract/757174
http://elempleo.com/cr/ofertas-trabajo/gerente-servicio-post-venta/757172
http://elempleo.com/cr/ofertas-trabajo/operario-de-proceso/757171
http://elempleo.com/cr/ofertas-trabajo/cajero-de-kiosco-ubicacion-area-metropolitana-fines-de-semana-disponibilidad-de-horarios/757170

如您所见,它显示20个url,这是可以的,但是如果我修改page_no=2page_no=3,... page_no=100并再次运行上述代码,它将返回与以前相同的结果;我需要本网站所有页面的所有URL。有人可以帮我吗?

此外,我在"area":40字段中设置了与sistemas类别相对应的Área de trabajo。它不会执行任何操作,因为结果不会被过滤为sistemas类别。

我在运行于Ubuntu 18.04的Python3中使用了beautifulsoup

也欢迎在R中使用rvest软件包的答案!

2 个答案:

答案 0 :(得分:1)

如果您尝试在打开Web控制台的情况下滚动浏览页面,则会注意到通过findByFilter javascript查询完成了分页。 Python请求无法处理这种页面修改。

findByFilter

您在这里有两个选择:

  1. 使用硒浏览器获取启用了javascript的抓取器
  2. 尝试模拟http://elempleo.com/cr/api/joboffers/findbyfilter POST请求的标头和请求有效载荷,并直接从api获取数据(这也很容易为您提供json响应,您可以将其直接放入python字典)。

答案 1 :(得分:1)

要设置硒,请访问此link

import time
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.common.exceptions import WebDriverException
url = "http://elempleo.com/cr/ofertas-empleo/"

注意:您需要从此link下载合适的浏览器驱动程序,并将其添加到系统环境变量的路径

# here I am using chrome webdriver
# setting up selenium
driver = webdriver.Chrome(executable_path=r"F:\Projects\sms_automation\chromedriver.exe")  # initialize webdriver instance
driver.get(url)  # open URL in browser
driver.find_element_by_id("ResultsByPage").send_keys('100')  # set items per page to 100
time.sleep(5)
soup = BeautifulSoup(driver.page_source, "html.parser")
url_set = ["http://elempleo.com"+i.get("href") for i in soup.select(".text-ellipsis")]
while True:
    try:
        driver.find_element_by_class_name("js-btn-next").click()  # go to next page
        time.sleep(3)
        soup = BeautifulSoup(driver.page_source, "html.parser")
        current_page_url = ["http://elempleo.com"+i.get("href") for i in soup.select(".text-ellipsis")]
        if url_set[-1] == current_page_url[-1]:
            break
        url_set += current_page_url
    except WebDriverException:
        time.sleep(5)

结果:

print(len(url_set))   # outputs 2641
print(url_set)  # outputs ['http://elempleo.comhttp://www.elempleo.com/cr/ofertas-trabajo/analista-de-sistemas-financieros/753845', 'http://elempleo.comhttp://www.elempleo.com/cr/ofertas-trabajo/balance-sheet-and-cash-flow-specialist/755211', 'http://elempleo.comhttp://www.elempleo.com/cr/ofertas-trabajo/coordinador-de-compensacion/757369', 'http://elempleo.comhttp://www.elempleo.com/cr/ofertas-trabajo/gerente-de-agronomia/757368', 'http://elempleo.comhttp://www.elempleo.com/cr/ofertas-trabajo/responsable-de-capacitacion-y-desempeno/757367', 'http://elempleo.comhttp://www.elempleo.com/cr/ofertas-trabajo/pmp-gestor-de-proyectos/757366', ....]