当前位置: 首页 > news >正文

用Haskell语言和wreq库配合HTTP写个爬虫程序

在 Haskell 中,wreq 库是一个非常方便的 HTTP 请求库,适合用来编写爬虫程序。你可以使用它来发送 GET 或 POST 请求,抓取网页内容,处理响应数据等。我们可以结合 HTTP 代理配置来实现网络请求。

下面我将展示如何在 Haskell 中使用 wreq 库配合 HTTP 请求编写一个爬虫程序。

在这里插入图片描述

1、安装 wreqhttp-client

首先,确保你已安装 wreq 库。你可以通过 cabal 安装它。wreq 依赖于 http-clienthttp-client-tls 库,因此需要一起安装。

cabal update
cabal install wreq

2、、导入必要模块

在 Haskell 中,我们需要导入以下模块:

import Control.Lens
import Network.Wreq
import qualified Data.ByteString.Lazy.Char8 as L8
import Network.HTTP.Client (newManager, defaultManagerSettings)
import Network.Wreq.Session (withSession)
import Data.Aeson
  • Control.Lens: 用于从 HTTP 请求和响应中提取数据。
  • Network.Wreq: 提供了发送 HTTP 请求的功能。
  • Data.ByteString.Lazy.Char8: 用于处理响应的字节流。
  • Network.HTTP.Client: 负责创建 HTTP 客户端和配置代理。
  • Network.Wreq.Session: 用于创建带有会话状态的请求,适合需要持续会话的爬虫任务。

3、设置 HTTP 代理

假设你需要使用 HTTP 代理服务器来发送请求,首先需要配置代理:

import Network.Wreq
import Network.HTTP.Client (newManager, defaultManagerSettings, managerModifyRequest)
import Network.HTTP.Client.TLS (tlsManagerSettings)

-- 设置 HTTP 代理
setupProxy :: IO Manager
setupProxy = do
  manager <- newManager tlsManagerSettings
  return $ managerModifyRequest manager $ \req -> do
    let proxy = "http://localhost:8080"  -- 代理地址
    setRequestProxy proxy req

在上面的代码中,我们创建了一个 setupProxy 函数,它将设置代理服务器地址。你可以根据实际需要修改代理的 URL。

4、发送 HTTP 请求并获取网页内容

我们将通过 wreq 库发送 HTTP 请求,抓取网页内容,并使用 Lens 提取响应体中的内容。以下是一个抓取网页内容并打印响应的简单例子:

import Network.Wreq
import Control.Lens
import Data.ByteString.Lazy.Char8 as L8

-- 使用代理发送 GET 请求并打印网页内容
fetchPage :: IO ()
fetchPage = do
    manager <- setupProxy
    let opts = defaults & manager .~ Just manager
    response <- getWith opts "https://www.example.com"  -- 目标网页
    L8.putStrLn (response ^. responseBody)  -- 打印网页的响应体

在这个例子中,getWith 函数通过代理发送 GET 请求,并获取目标网页的响应内容。responseBody 是通过 Lens 提取响应体内容,我们将其打印到控制台。

5、处理 JSON 响应

如果你抓取的是 JSON 数据,可以使用 aeson 库来解析 JSON 响应。wreqaeson 库结合得很好,允许你直接将 JSON 响应转化为 Haskell 数据类型。

假设我们从 API 获取 JSON 数据,并解析它:

import Network.Wreq
import Control.Lens
import Data.Aeson
import Data.Maybe (fromJust)

-- 假设我们有一个 JSON 响应,格式为:{"id": 1, "name": "example"}
data Response = Response {
    id :: Int,
    name :: String
} deriving (Show)

instance FromJSON Response where
    parseJSON = withObject "Response" $ \v -> Response
        <$> v .: "id"
        <*> v .: "name"

-- 使用代理发送 GET 请求并解析 JSON 响应
fetchJson :: IO ()
fetchJson = do
    manager <- setupProxy
    let opts = defaults & manager .~ Just manager
    response <- getWith opts "https://jsonplaceholder.typicode.com/users/1"
    
    let jsonResponse = response ^. responseBody
    let parsedData = decode jsonResponse :: Maybe Response
    case parsedData of
        Just data' -> print data'
        Nothing -> putStrLn "Failed to parse JSON"

在这个例子中,Response 是我们定义的一个数据类型,用来表示 JSON 响应的数据结构。FromJSON 实例使得我们能够从 JSON 数据中提取字段。decode 函数将 JSON 响应解析为 Response 类型。

6、完整示例:通过代理抓取网页并解析数据

最后,以下是一个完整的示例,展示如何使用 wreq 配合代理抓取网页,并解析其 JSON 数据:

import Network.Wreq
import Control.Lens
import Network.HTTP.Client (newManager, defaultManagerSettings, managerModifyRequest)
import Network.HTTP.Client.TLS (tlsManagerSettings)
import Data.Aeson
import qualified Data.ByteString.Lazy.Char8 as L8
import Data.Maybe (fromJust)

-- 设置代理
setupProxy :: IO Manager
setupProxy = do
    manager <- newManager tlsManagerSettings
    return $ managerModifyRequest manager $ \req -> do
        let proxy = "http://localhost:8080"  -- 设置代理地址
        setRequestProxy proxy req

-- 数据类型用于解析 JSON
data Response = Response {
    id :: Int,
    name :: String
} deriving (Show)

instance FromJSON Response where
    parseJSON = withObject "Response" $ \v -> Response
        <$> v .: "id"
        <*> v .: "name"

-- 使用代理发送 GET 请求并解析 JSON
fetchJson :: IO ()
fetchJson = do
    manager <- setupProxy
    let opts = defaults & manager .~ Just manager
    response <- getWith opts "https://jsonplaceholder.typicode.com/users/1"
    
    -- 解析 JSON 响应
    let jsonResponse = response ^. responseBody
    let parsedData = decode jsonResponse :: Maybe Response
    case parsedData of
        Just data' -> print data'
        Nothing -> putStrLn "Failed to parse JSON"

main :: IO ()
main = fetchJson

7、总结

在这个 Haskell 示例中,我们展示了如何使用 wreq 库配合 HTTP 代理进行网络请求,并抓取网页内容或 API 返回的 JSON 数据。主要步骤包括:

  1. 配置 HTTP 代理。
  2. 使用 wreq 发送 HTTP 请求。
  3. 使用 Lens 提取响应体内容。
  4. 使用 Aeson 库解析 JSON 数据。

我们可以根据需要扩展这个爬虫程序,添加更多的请求头、POST 请求支持、错误处理等。

相关文章:

  • Java学习--Redis
  • vulnhub靶场【digitalworld.local系列】的electrical靶机
  • Rabbitmq--延迟消息
  • HTML星球大冒险之路线图
  • 程序设计语言基础知识概述
  • 微服务项目如何部署?
  • 程序化广告知识入门与Python基础数据处理实践
  • 【C++】 —— 笔试刷题day_1
  • RHEL/CentOS 7.9使用firewalld限制出方向策略
  • Javaweb后端文件上传@value注解
  • 操作系统之进程状态、优先级和切换与调度
  • 【C语言基础】变量与算术表达式介绍
  • SpringBoot -拦截器Interceptor、过滤器 Filter 及设置
  • SpringBoot使用Nacos进行application.yml配置管理
  • 日期类、Date、Calendar、IO 流、File
  • Uniapp实现地图获取定位功能
  • 基于muduo+mysql+jsoncpp的简易HTTPWebServer
  • linux wifi driver深度实践之内核编译加载
  • 从零构建CNN:框架与自定义实现对比
  • 本地部署Hive集群
  • 国宝归来!子弹库帛书二、三卷抵达北京
  • 信俗与共:清代新疆回疆儒释道庙宇的中华政教
  • 国寿资产获批参与第三批保险资金长期投资改革试点
  • 广西壮族自治区党委副书记、自治区政府主席蓝天立接受审查调查
  • 昆明公布3起经济犯罪案例:一人持有820余万假美元被判刑十年
  • 贝壳一季度收入增长42%:二手房市场活跃度维持在高位