无法解析的Ajax,selenium+chromedriver实战爬取

对于有规律的Ajax请求,我们可以分析它的特点,从而抓取一个又一个的Ajax去获取请求,但,有些网站为了反爬,它的Ajax是没有规律的,我们举个例子,拉勾网

我们进入拉勾网,搜索python,检查,切换到network,过滤请求,这里只要Ajax请求,下滑到底部,点击下一页:

图中标有1,2的两个请求,就是包含职位信息的Ajax请求,分别是第一页的和第二页的,我们可以发现,两个Request URL是一样的,也就是说,这里并没有参数让我们区分不同的Ajax请求有什么区别,而且,如果你访问这个Ajax,即使是浏览器也会这样:

更不用说爬虫了。

那针对这样的网站,我们怎么能获取大量数据呢。

我们这次的目的是,爬取详细信息,多页。我们需要,selenium,chromedriver,lxml,MongoDB

先上代码

from selenium import webdriver
from lxml import etree
import time
from pymongo import MongoClient

client = MongoClient()
db = client['LaGou']
collection = db['lagou_position']

#写入chromedriver路径
driver_path = r"D:\pythontools\chromedriver.exe"
driver = webdriver.Chrome(executable_path=driver_path)

def parse_page(url):
    driver.get(url)
    while True:
        resp = driver.page_source
        # print(resp)
        text = etree.HTML(resp)
        position_links = text.xpath("//a[@class='position_link']/@href")
        next_btn = driver.find_element_by_class_name("pager_next ")
        # next_btn.click()
        for position_link in position_links:
            # print(position_link)
            parse_detail_page(position_link)
        if "pager_next pager_next_disabled" in next_btn.get_attribute("class"):
            break
        else:
            next_btn.click()
        time.sleep(1)

def parse_detail_page(position_link):
    position = {}
    driver.execute_script("window.open('%s')"%position_link)
    driver.switch_to.window(driver.window_handles[1])
    resp = driver.page_source
    text = etree.HTML(resp)
    position_name = text.xpath("//span[@class='name']/text()")[0]
    position_producer = text.xpath("//span[@class='name']/text()")[1]
    position_salary = text.xpath("//dd[@class='job_request']//span/text()")[0]
    position_city = text.xpath("//dd[@class='job_request']//span/text()")[1]
    position_undergo = text.xpath("//dd[@class='job_request']//span/text()")[2]
    position_edu = text.xpath("//dd[@class='job_request']//span/text()")[3]
    position_detail = text.xpath("//div[@class='job-detail']//p/text()")
    # print(position_detail)
    # print(position_salary,position_city,position_undergo,position_edu)
    # print(position_salary)
    # print(position_name)
    # print(position_producer)
    position["职位名称"] = position_name
    position["发布者"] = position_producer
    position["薪资"] = position_salary
    position["城市"] = position_city
    position["经验要求"] = position_undergo
    position["学历背景"] = position_edu
    position["职位描述"] = position_detail
    save_to_mongo(position)
    driver.close()
    driver.switch_to.window(driver.window_handles[0])

def save_to_mongo(position):
    if collection.insert(position):
        print("Sava is ok!")

def main():
    url = "https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput="
    parse_page(url)

if __name__ == '__main__':
    main()

注释内容为测试数据。仅参考。

我们来分析代码实现原理。

我们依旧用了一个main函数来传主页url,需要注意到,你点击下一页是,网页链接并不会变化,只是在用Ajax请求进行数据交互

是不随你改变页面而改变的。

我们定义了一个parse_page,处理第一页第二页这样的页面,提取详细职位的href属性,让parse_detail_page去点击,模拟浏览器进入到详情页,我们还获取了下一页的按钮,如果有下一页就点击,没有就退出:

if "pager_next pager_next_disabled" in next_btn.get_attribute("class"):
    break
else:
    next_btn.click()

我们应该注意到,最后一页的next_btn的class属性和其他是不一样的。

我们再看parse_detail_page,它用来处理详情页,我们要注意,我们要在新窗口打开,不能直接get打开,否则覆盖了主页,就无法进行翻页点击。

然后通过窗口下标去切换到详情页。

存储信息进mongo后,关闭窗口,切换回主页。

代码运行的时候,可以看见浏览器一直在切换和翻页。

我们看下数据库,我的compass安装好了,另外,备注一下compass的一个特点吧,

一:先打开mongo才能连接。

二:如果你打开了mongo,在打开compass,完成需要工作后,关闭compass,再次点击compass会error:

像这样,原因是,直接关闭对compass是没用的,你需要ctrl+shift+esc找到compass,结束进程在启动即可。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值