searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

利用爬虫获取页面数据

2024-05-15 06:46:05
22
0

本文列举两种常见的爬虫方案,旨在清晰化爬虫的常见流程。

利用爬虫抓取接口数据

此种方案需要明确待爬取的接口,以及爬取的数据字段

 

利用requests库,是基于urllib,采用Apache2 Licensed开源协议的 HTTP 库。

import requests

引入之后,需要写请求报文的逻辑

请求报文的字段列表直接copy待爬取接口的字段列表

 

标准的请求代码逻辑如下:

response = requests.get(
        url='请求url',
        headers={
            xxx: yyy
        }
    )
    region_list = []
    if response.status_code == 200:
        data = response.json()
        print('data获取成功!')
    else:
        print("Failed to retrieve data. Status code:", response.status_code)

收到response响应体后,解析出想要的字段,可以写入到csv表格中

# 写入 CSV 文件,按要求写入数据
    with open(file_path, mode='w', newline='', encoding='utf-8') as file:
        writer = csv.writer(file)
        writer.writerow(['字段1', '字段2', '字段...'])
        print('文件写入成功!')

同时,为了清晰文件对应的爬取数据之间的对应关系,可以对文件进行重命名

但是部分接口存在对response内容值加密行为,我们需要找到对应的解密文件,进行解密即可

 

利用爬虫抓取DOM数据

待爬虫的数据并不一定是由接口返回,部分可能是前端写死的数据,我们可以直接将数据copy到本地,但是页面的数据后期可能会发生变化,因此为了避免每次都需要从页面中查找并copy数据,可以利用爬虫,直接对相对应DOM部分进行爬取

爬取DOM数据利用Selenium库,它是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。

# 提供用于模拟用户在网页上进行交互的方法和功能。
from selenium import webdriver
# 用于在 WebDriver 中执行鼠标和键盘操作的高级方法
from selenium.webdriver import ActionChains
# 提供了用于定位网页元素的方法
from selenium.webdriver.common.by import By
# 提供了显式等待的功能
from selenium.webdriver.support.ui import WebDriverWait
# 一系列预定义的等待条件
from selenium.webdriver.support import expected_conditions as EC
# 用于启动浏览器驱动程序的服务
from selenium.webdriver.chrome.service import Service

使用这些包之前需要下载浏览器对应的driver,用于浏览器与Selenium进行通信的载体。

 
 

chrome对应的driver版本可在chromedriver.com网址查看

使用Selenium库时,需要一系列预配置,具体配置信息如下:

# 文件加载目录
download_dir = "C:\\Users\\Administrator\\Desktop\\Data"
# 用于配置 Chrome 浏览器的行为
chrome_options = webdriver.ChromeOptions()
# 添加了一系列偏好设置
chrome_options.add_experimental_option("prefs", {
    "download.default_directory": download_dir, # 保存到指定的目录
    "download.prompt_for_download": False, # 禁用下载前的提示框
    "safebrowsing.enabled": True # 启用安全浏览功能,检查下载文件的安全性
})

chromedriver_path = 'C:/Program Files (x86)/Google/Chrome/Application/chromedriver.exe'
# 指定 Chromedriver 的路径
service = Service(chromedriver_path)
driver = webdriver.Chrome(service=service, options=chrome_options)
wait = WebDriverWait(driver, 10)  # 增加等待时间为10秒

接下来就是启动浏览器,爬取对应DOM:

try:
        driver.get(url)

        # 点击“yyy”按钮
        button_xpath = "//div[@class='xxx' and text()='yyy']"
        button = wait.until(EC.element_to_be_clickable((By.XPATH, button_xpath)))
        button.click()

        # 获取页面元素
        page_dom = driver.page_source
        soup = BeautifulSoup(page_dom, 'html.parser')
        iframe_id_element = soup.find('iframe', id='iframe')
        if iframe_id_element:
            # 如果找到了 id 为 "iframe" 的 iframe 元素
            # 获取 iframe 的内容
            src_value = iframe_id_element['src']
            full_url = 'https:' + src_value
            driver.get(full_url)
            wait = WebDriverWait(driver, 10)
            time.sleep(10)
            trigger_element = wait.until(EC.presence_of_element_located((By.CLASS_NAME, "ant-dropdown-trigger")))
            # 将鼠标移动到第一个元素上
            action = ActionChains(driver)
            action.move_to_element(trigger_element).perform()

            # 等待一段时间,确保下拉菜单已完全展开
            time.sleep(4)

            sub_menu_path = "//li[@class='aaa' and text()='bbb']"
            sub_menu_element = wait.until(EC.element_to_be_clickable((By.XPATH, sub_menu_path)))
            # 将鼠标从第一个元素移到下拉菜单中的第一个选项
            action.move_to_element(sub_menu_element).click().perform()
        else:
            print("未找到id为iframe的iframe元素")

    finally:
        # 等待一段时间,确保文件的数据已经下完
        time.sleep(10)
        driver.quit()

具体针对于DOM元素的定位,以及DOM元素的交互行为可以详细查阅Selenium,此处不再赘述。

但是,部分网站是直接屏蔽Selenium:

因为selenium在命令行手动开启后的谷歌浏览器加了一些变量值,比如window.navigator.webdriver,在正常的谷歌浏览器是undefined,在selenium打开的谷歌浏览器是True,然后对方服务器就会下发js代码,检测这个变量值给网站,网站判断这个值,为True就是爬虫程序就封锁你的访问

因此,我们需要对Selenium隐藏操作,在请求之前改变一些参数,绕过检测,具体细节可以自己了解下网站检测selenium的原理,需要设置对应其它的值都可以加:

# chrome在79版之前用下面两行代码
#options.add_experimental_option("excludeSwitches", ["enable-automation"])
#options.add_experimental_option('useAutomationExtension', False)
 


# -chrome在79和79版之后用这个,
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
    "source": """
    Object.defineProperty(navigator, 'webdriver', {
      get: () => undefined
    })
  """
})
driver.get("这里填写你被反爬网站的链接")

选择合适的爬虫方案应根据具体需求和团队技术栈来决定。上述方案仅仅是爬虫方案中的两种,欢迎大家进行补充!

0条评论
0 / 1000
w****n
17文章数
1粉丝数
w****n
17 文章 | 1 粉丝
原创

利用爬虫获取页面数据

2024-05-15 06:46:05
22
0

本文列举两种常见的爬虫方案,旨在清晰化爬虫的常见流程。

利用爬虫抓取接口数据

此种方案需要明确待爬取的接口,以及爬取的数据字段

 

利用requests库,是基于urllib,采用Apache2 Licensed开源协议的 HTTP 库。

import requests

引入之后,需要写请求报文的逻辑

请求报文的字段列表直接copy待爬取接口的字段列表

 

标准的请求代码逻辑如下:

response = requests.get(
        url='请求url',
        headers={
            xxx: yyy
        }
    )
    region_list = []
    if response.status_code == 200:
        data = response.json()
        print('data获取成功!')
    else:
        print("Failed to retrieve data. Status code:", response.status_code)

收到response响应体后,解析出想要的字段,可以写入到csv表格中

# 写入 CSV 文件,按要求写入数据
    with open(file_path, mode='w', newline='', encoding='utf-8') as file:
        writer = csv.writer(file)
        writer.writerow(['字段1', '字段2', '字段...'])
        print('文件写入成功!')

同时,为了清晰文件对应的爬取数据之间的对应关系,可以对文件进行重命名

但是部分接口存在对response内容值加密行为,我们需要找到对应的解密文件,进行解密即可

 

利用爬虫抓取DOM数据

待爬虫的数据并不一定是由接口返回,部分可能是前端写死的数据,我们可以直接将数据copy到本地,但是页面的数据后期可能会发生变化,因此为了避免每次都需要从页面中查找并copy数据,可以利用爬虫,直接对相对应DOM部分进行爬取

爬取DOM数据利用Selenium库,它是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。

# 提供用于模拟用户在网页上进行交互的方法和功能。
from selenium import webdriver
# 用于在 WebDriver 中执行鼠标和键盘操作的高级方法
from selenium.webdriver import ActionChains
# 提供了用于定位网页元素的方法
from selenium.webdriver.common.by import By
# 提供了显式等待的功能
from selenium.webdriver.support.ui import WebDriverWait
# 一系列预定义的等待条件
from selenium.webdriver.support import expected_conditions as EC
# 用于启动浏览器驱动程序的服务
from selenium.webdriver.chrome.service import Service

使用这些包之前需要下载浏览器对应的driver,用于浏览器与Selenium进行通信的载体。

 
 

chrome对应的driver版本可在chromedriver.com网址查看

使用Selenium库时,需要一系列预配置,具体配置信息如下:

# 文件加载目录
download_dir = "C:\\Users\\Administrator\\Desktop\\Data"
# 用于配置 Chrome 浏览器的行为
chrome_options = webdriver.ChromeOptions()
# 添加了一系列偏好设置
chrome_options.add_experimental_option("prefs", {
    "download.default_directory": download_dir, # 保存到指定的目录
    "download.prompt_for_download": False, # 禁用下载前的提示框
    "safebrowsing.enabled": True # 启用安全浏览功能,检查下载文件的安全性
})

chromedriver_path = 'C:/Program Files (x86)/Google/Chrome/Application/chromedriver.exe'
# 指定 Chromedriver 的路径
service = Service(chromedriver_path)
driver = webdriver.Chrome(service=service, options=chrome_options)
wait = WebDriverWait(driver, 10)  # 增加等待时间为10秒

接下来就是启动浏览器,爬取对应DOM:

try:
        driver.get(url)

        # 点击“yyy”按钮
        button_xpath = "//div[@class='xxx' and text()='yyy']"
        button = wait.until(EC.element_to_be_clickable((By.XPATH, button_xpath)))
        button.click()

        # 获取页面元素
        page_dom = driver.page_source
        soup = BeautifulSoup(page_dom, 'html.parser')
        iframe_id_element = soup.find('iframe', id='iframe')
        if iframe_id_element:
            # 如果找到了 id 为 "iframe" 的 iframe 元素
            # 获取 iframe 的内容
            src_value = iframe_id_element['src']
            full_url = 'https:' + src_value
            driver.get(full_url)
            wait = WebDriverWait(driver, 10)
            time.sleep(10)
            trigger_element = wait.until(EC.presence_of_element_located((By.CLASS_NAME, "ant-dropdown-trigger")))
            # 将鼠标移动到第一个元素上
            action = ActionChains(driver)
            action.move_to_element(trigger_element).perform()

            # 等待一段时间,确保下拉菜单已完全展开
            time.sleep(4)

            sub_menu_path = "//li[@class='aaa' and text()='bbb']"
            sub_menu_element = wait.until(EC.element_to_be_clickable((By.XPATH, sub_menu_path)))
            # 将鼠标从第一个元素移到下拉菜单中的第一个选项
            action.move_to_element(sub_menu_element).click().perform()
        else:
            print("未找到id为iframe的iframe元素")

    finally:
        # 等待一段时间,确保文件的数据已经下完
        time.sleep(10)
        driver.quit()

具体针对于DOM元素的定位,以及DOM元素的交互行为可以详细查阅Selenium,此处不再赘述。

但是,部分网站是直接屏蔽Selenium:

因为selenium在命令行手动开启后的谷歌浏览器加了一些变量值,比如window.navigator.webdriver,在正常的谷歌浏览器是undefined,在selenium打开的谷歌浏览器是True,然后对方服务器就会下发js代码,检测这个变量值给网站,网站判断这个值,为True就是爬虫程序就封锁你的访问

因此,我们需要对Selenium隐藏操作,在请求之前改变一些参数,绕过检测,具体细节可以自己了解下网站检测selenium的原理,需要设置对应其它的值都可以加:

# chrome在79版之前用下面两行代码
#options.add_experimental_option("excludeSwitches", ["enable-automation"])
#options.add_experimental_option('useAutomationExtension', False)
 


# -chrome在79和79版之后用这个,
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
    "source": """
    Object.defineProperty(navigator, 'webdriver', {
      get: () => undefined
    })
  """
})
driver.get("这里填写你被反爬网站的链接")

选择合适的爬虫方案应根据具体需求和团队技术栈来决定。上述方案仅仅是爬虫方案中的两种,欢迎大家进行补充!

文章来自个人专栏
Vue前端开发
17 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
1
1