使用Ajax技术进行动态网页的爬虫(pycharm)

发布于:2025-03-18 ⋅ 阅读:(18) ⋅ 点赞:(0)

Ajax(Asynchronous JavaScript and XML)技术在现代Web开发中广泛应用。

它允许网页在不重新加载整个页面的情况下,通过JavaScript与服务器进行异步通信,动态更新部分内容。这种技术对爬虫的功能和作用产生了显著影响,主要体现在以下几个方面:

1. 动态内容加载

  • 传统网页:内容在页面加载时一次性生成,爬虫可以直接从HTML源码中提取数据。

  • Ajax网页:内容通过JavaScript异步加载,初始HTML源码中可能不包含完整数据,爬虫需要执行JavaScript才能获取动态生成的内容。

2. 爬虫的复杂性增加

  • 传统爬虫:只需解析静态HTML即可获取数据。

  • Ajax爬虫:需要模拟浏览器行为,执行JavaScript并等待异步请求完成,增加了爬虫的复杂性和资源消耗。

3. 数据获取的延迟

  • 传统网页:数据在页面加载时即可获取。

  • Ajax网页:数据可能在页面加载后通过异步请求获取,爬虫需要等待数据加载完成,增加了抓取时间。

4. 反爬虫机制的利用

  • Ajax技术:常被用于实现反爬虫机制,如动态生成令牌、验证用户行为等,增加了爬虫的抓取难度。

5. 爬虫工具的演进

  • 传统工具:如requestsBeautifulSoup等,适用于静态网页。

  • 现代工具:如SeleniumPuppeteer等,能够模拟浏览器行为,执行JavaScript,适用于Ajax网页。

6. 数据更新的实时性

  • Ajax网页:数据可以实时更新,爬虫需要定期抓取以获取最新数据。

  • 传统网页:数据更新需要重新加载页面,爬虫抓取频率相对较低。

7. API接口的利用

  • Ajax请求:通常通过API接口获取数据,爬虫可以直接调用这些接口获取结构化数据,绕过页面渲染的复杂性。

总结

Ajax技术使得网页内容动态化,增加了爬虫抓取的难度和复杂性。现代爬虫需要模拟浏览器行为,执行JavaScript,并处理异步请求,才能有效抓取Ajax网页中的数据。同时,Ajax技术也为爬虫提供了直接调用API接口获取数据的机会,简化了部分抓取过程。

以简书的网页爬虫为例 :

人气小哥 - 简书https://www.jianshu.com/u/b14b55bc66ae

 

具体爬取步骤:

 

写代码来爬取一个链家房源的爬取(由于反爬虫的限制,一般尝试一次就好)

首先要配置好运行环境:

下载安装selenium 打开cmd 后面那个是清华的镜像源: 

Https://pypi.tuna.tsinghua.edu.cn/simple

下载Chromedriver:

 打开谷歌浏览器找到版本是什么:

 

打开设置 然后搜索version找到版本:

 

之后寻找下载的源 :

Chrome for Testing availability  进入网址

然后找到自己谷歌浏览器对应的版本: 

 

下载之后 复制所在的目录 尽量将安装包解压后放在 纯英文的目录下 可以自己创建!

 

这就可以配置chromedriver的使用路径了 。

接下来以淄博链家房源的价格信息为例 爬取动态内容:

淄博二手房房源_淄博二手房出售|买卖|交易信息(淄博链家)淄博链家二手房频道,发布淄博二手房真实在售房源信息,为您提供淄博二手房房源出售、二手房买卖交易等信息,快速查询淄博二手房房价、特色、带看情况等.链家,连接每个家的故事.https://zb.lianjia.com/ershoufang/

 使用XPATH

进行代码展示:

 通过列表页进入跳转详情页然后怕爬取结果之后关闭详情页在进行跳转

import time
from lxml import etree
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By

# 配置 ChromeDriver
driver_path = r"D:\chromdriver\chromedriver-win64\chromedriver.exe"
service = Service(executable_path=driver_path)


# 解析详情页
def parse_detail_page(link):
    driver.execute_script("window.open('%s')" % link)
    driver.switch_to.window(driver.window_handles[1])

    # 等待详情页加载完成
    WebDriverWait(driver, timeout=10).until(
        EC.presence_of_element_located((By.XPATH, '//div[@class="price-container"]'))
    )

    # 解析详情页信息
    parse_detail_info(driver.page_source)

    # 关闭详情页,切换回列表页
    time.sleep(2)
    driver.close()
    driver.switch_to.window(driver.window_handles[0])


# 解析详情页信息
def parse_detail_info(source):
    html = etree.HTML(source)
    # 示例:提取价格信息
    price = html.xpath('//div[@class="price-container"]//span[@class="total"]/text()')
    print("价格:", price[0] if price else "未知")


# 主循环
while True:
    driver = webdriver.Chrome(service=service)
    driver.get("https://zb.lianjia.com/ershoufang/")

    # 等待列表页加载完成
    WebDriverWait(driver, timeout=10).until(
        EC.presence_of_element_located((By.XPATH, '//div[@class="leftContent"]//ul[@class="sellListContent"]'))
    )

    html = etree.HTML(driver.page_source)
    lis = html.xpath('//div[@class="leftContent"]//ul[@class="sellListContent"]/li')

    for li in lis:
        try:
            link = li.xpath(".//a/@href")[0]  # 调整 XPath 表达式
            parse_detail_page(link)
        except IndexError:
            print("未找到链接,跳过该条目")
            continue

    # 单击下一页按钮
    try:
        next_btn = driver.find_element(By.XPATH, "//div[@class='page-box house-lst-page-box']/a[last()]")
        if "disabled" in next_btn.get_attribute("class"):
            break
        else:
            driver.execute_script("arguments[0].click();", next_btn)
    except Exception as e:
        print("未找到下一页按钮或无法点击:", e)
        break

# 关闭浏览器
driver.quit()

这段代码是一个使用 Selenium 和 lxml 库实现的链家网二手房数据爬虫。它的主要功能是爬取链家网某个城市(如淄博)的二手房列表页,并提取每个房源的详情页信息(例如价格)。

1. 导入库

import time
from lxml import etree
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
  • time:用于设置延迟。

  • lxml.etree:用于解析 HTML 文档,提取数据。

  • selenium.webdriver:用于控制浏览器,模拟用户操作。

  • Service:用于配置 ChromeDriver 服务。

  • expected_conditions 和 WebDriverWait:用于等待页面加载完成。

  • By:用于定位页面元素。


2. 配置 ChromeDriver

driver_path = r"D:\chromdriver\chromedriver-win64\chromedriver.exe"
service = Service(executable_path=driver_path)
  • driver_path:指定 ChromeDriver 的路径。

  • Service:创建一个 ChromeDriver 服务对象。


3. 解析详情页

def parse_detail_page(link):
    driver.execute_script("window.open('%s')" % link)
    driver.switch_to.window(driver.window_handles[1])

    # 等待详情页加载完成
    WebDriverWait(driver, timeout=10).until(
        EC.presence_of_element_located((By.XPATH, '//div[@class="price-container"]'))
    )

    # 解析详情页信息
    parse_detail_info(driver.page_source)

    # 关闭详情页,切换回列表页
    time.sleep(2)
    driver.close()
    driver.switch_to.window(driver.window_handles[0])
  • 功能

    • 打开房源的详情页。

    • 等待详情页加载完成。

    • 解析详情页信息(例如价格)。

    • 关闭详情页,切换回列表页。

  • 实现

    • driver.execute_script("window.open('%s')" % link):在新标签页中打开详情页。

    • driver.switch_to.window(driver.window_handles[1]):切换到详情页标签页。

    • WebDriverWait:等待详情页中的某个元素(//div[@class="price-container"])加载完成。

    • parse_detail_info(driver.page_source):调用函数解析详情页信息。

    • driver.close():关闭详情页标签页。

    • driver.switch_to.window(driver.window_handles[0]):切换回列表页标签页。


4. 解析详情页信息

def parse_detail_info(source):
    html = etree.HTML(source)
    # 示例:提取价格信息
    price = html.xpath('//div[@class="price-container"]//span[@class="total"]/text()')
    print("价格:", price[0] if price else "未知")
  • 功能

    • 解析详情页的 HTML 源代码,提取价格信息。

  • 实现

    • etree.HTML(source):将 HTML 源代码解析为 lxml 可操作的文档树。

    • html.xpath:使用 XPath 表达式提取价格信息。

    • print("价格:", price[0] if price else "未知"):打印价格信息。


5. 主循环

while True:
    driver = webdriver.Chrome(service=service)
    driver.get("https://zb.lianjia.com/ershoufang/")

    # 等待列表页加载完成
    WebDriverWait(driver, timeout=10).until(
        EC.presence_of_element_located((By.XPATH, '//div[@class="leftContent"]//ul[@class="sellListContent"]'))
    )

    html = etree.HTML(driver.page_source)
    lis = html.xpath('//div[@class="leftContent"]//ul[@class="sellListContent"]/li')

    for li in lis:
        try:
            link = li.xpath(".//a/@href")[0]  # 调整 XPath 表达式
            parse_detail_page(link)
        except IndexError:
            print("未找到链接,跳过该条目")
            continue

    # 单击下一页按钮
    try:
        next_btn = driver.find_element(By.XPATH, "//div[@class='page-box house-lst-page-box']/a[last()]")
        if "disabled" in next_btn.get_attribute("class"):
            break
        else:
            driver.execute_script("arguments[0].click();", next_btn)
    except Exception as e:
        print("未找到下一页按钮或无法点击:", e)
        break
  • 功能

    • 打开链家网的二手房列表页。

    • 等待列表页加载完成。

    • 提取每个房源的链接,并调用 parse_detail_page 函数解析详情页信息。

    • 点击“下一页”按钮,继续爬取下一页数据。

  • 实现

    • driver.get("https://zb.lianjia.com/ershoufang/"):打开链家网的二手房列表页。

    • WebDriverWait:等待列表页中的某个元素(//div[@class="leftContent"]//ul[@class="sellListContent"])加载完成。

    • html.xpath('//div[@class="leftContent"]//ul[@class="sellListContent"]/li'):提取列表页中的房源条目。

    • li.xpath(".//a/@href")[0]:提取每个房源的详情页链接。

    • parse_detail_page(link):调用函数解析详情页信息。

    • next_btn:查找“下一页”按钮。

    • driver.execute_script("arguments[0].click();", next_btn):点击“下一页”按钮。


6. 关闭浏览器

driver.quit()
  • 功能

    • 关闭浏览器,结束爬虫任务。


代码功能总结

  1. 打开链家网二手房列表页,并等待页面加载完成。

  2. 提取每个房源的详情页链接,并打开详情页。

  3. 解析详情页信息(例如价格),并打印结果。

  4. 翻页功能:点击“下一页”按钮,继续爬取下一页数据。

  5. 异常处理:跳过没有链接的房源条目,捕获并处理页面加载超时等错误。

  6. 关闭浏览器:在所有操作完成后关闭浏览器。


注意事项

  1. 反爬虫机制

    • 链家网可能会检测到爬虫行为,限制访问频率或返回错误页面。建议增加随机延迟或使用代理 IP。

  2. 页面结构变化

    • 如果链家网的页面结构发生变化,需要调整 XPath 表达式。

  3. 网络问题

    • 如果网络连接不稳定,可能导致页面加载失败。建议增加重试机制。

 运行结果:

他会一边爬一边打开爬完之后关闭详情页 一直循环。

如果这种情况就是反爬机制的阻挠 或者是timeout爬取的时间不够 可以适当增大!

 

 


网站公告

今日签到

点亮在社区的每一天
去签到