• (四)爬虫之动态网页


      对于网页上的有些内容,需要进行一定的交互操作,才能拿到相应的数据,例如常见的ajax请求等。为了抓取ajax请求的结果,可以通过ajax请求的url,抓取返回结果,也可以利用Selenium模块来模拟网页ajax。简单记录下一段学习过程。

    1.问题分析

      如下面我爱我家的网页中(https://wh.5i5j.com/ershoufang/),当在搜索框中输入“保”时,后台会自动发送ajax请求,拿到所有包含“保”字的小区名字。

       

      通过network分析可以看到ajax请求的返回一个json对象:

    2. 抓取数据

      2.1 利用requests

        构造ajax请求的url,利用ajax请求,分析拿到的json数据,代码如下:

    #coding:utf-8
    import requests
    import json
    from lxml import html
    
    url="https://wh.5i5j.com/ajaxsearch?status=ershoufang&keywords=%s"%(u'')
    response = requests.get(url,headers={'User-Agent':"Mozilla/5.0 (Windows NT 6.1; r…) Gecko/20100101 Firefox/64.0"})
    html_string = json.loads(response.text)['res']
    tree = html.fromstring(html_string)
    li_tags=tree.getchildren()
    house_info={}
    for tag in li_tags:
        name = tag.xpath('.//div/span[@class="name"]/text()')[0]
        count = tag.xpath('.//span[@class="tao"]/text()')[0]
        print name,count
        house_info[name]=count
    # print house_info

      2.2 利用selenium

        selenium可以模拟浏览器的行为,因此可以用来作为爬虫使用(但速度较慢),模拟浏览器访问网站。

        安装selenium:pip install selenium

        (下载浏览器驱动:第一次使用selenium时,可能会报错selenium.common.exceptions.WebDriverException,这是因为需要下载模拟的浏览器的驱动,下载地址https://github.com/SeleniumHQ/selenium/tree/master/py#drivers

        selenium的使用参考:http://www.aneasystone.com/archives/2018/02/python-selenium-spider.html

        使用selenium抓取上面数据的代码如下:

    from selenium import webdriver
    
    driver = webdriver.Firefox(executable_path='D:\Python\geckodriver.exe')  #路径为下载的浏览器驱动保存路径
    driver.get('https://wh.5i5j.com/zufang/')  #打开网页
    kw = driver.find_element_by_id("zufang")   #找到搜索框
    kw.send_keys(u"")                         #搜索框中输入文字 “万”
    # button = driver.find_element_by_class_name("btn-search")
    # button.click()
    driver.implicitly_wait(30)  #隐式等待30秒,浏览器查找每个元素时,若未找到会等待30s,30s还未找到时报错
    li_tags = driver.find_elements_by_css_selector('ul.search_w li')  #注意此处是find_elements, 复数查找多个element
    for li_tag in li_tags:
        name = li_tag.find_element_by_class_name('name').text
        count = li_tag.find_element_by_class_name('tao').text
        print name, count

       上面代码中,由于ajax请求执行完成需要时间,driver.implicitly_wait(30)让浏览器隐式等待30秒,即浏览器查找每个元素时,若未找到会等待30s,30s后还未找到时会报错。

    关于selenium的等待有显示等待和隐式等待。(区别参考:https://www.cnblogs.com/dsy-sun/articles/6594866.html

      显示等待:明确说明等待某个元素出现或条件成立时,如下面代码:   

    newWebDriverWait(driver,15).until(        
    ExpectedConditions.presenceOfElementLocated(By.cssSelector("css locator")));

      隐式等待:全局的,对所有元素都有效,找不到该元素时会等待设定时间,如上面的driver.implicitly_wait(30)

      

  • 相关阅读:
    云服务器迁移的那些事之一
    《编译原理》(第二版)第一章的学习笔记(一)
    vs 实用扩展
    SQL多的是,你不知道的事
    Entity Framework 批量插入 提速
    oracle 回收已删除的表
    发现一个奇怪的问题!
    看到易办网的希望...
    asp.net不认为数据库字段的空值为null
    什么是伪url?
  • 原文地址:https://www.cnblogs.com/silence-cho/p/10164870.html
Copyright © 2020-2023  润新知