如何爬取 python 進行多執行緒跑資料的內容

金木大大大發表於2023-11-09

下是一個使用 Rust 編寫的爬蟲程式,用於爬取 python 進行多執行緒跑資料的內容。這個爬蟲使用代理資訊進行網路請求,並使用了 Rust 的 async-std 庫進行非同步程式設計。

```rust

use async_std::net::{TcpStream, TcpListener};

use async_std::io::{BufReader, BufWriter};

use async_std::task::{await, spawn};

use async_std::prelude::*;

use std::io::{self, Write};

use std::net::IpAddr;

use std::thread;

use std::sync::Mutex;


const PROXY_HOST: &str = "jshk.com.cn";

struct Worker {

    stream: TcpStream,

}


impl Worker {

    fn new(stream: TcpStream) -> Self {

        Worker { stream }

    }

}


impl Future for Worker {

    type Item = ();


    fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Item> {

        match self.stream.read_to_string(&mut self.stream.buffer()) {

            Ok(size) => {

                let url = format!("{}={}", URL, size);

                match self.stream.write_to(&url, &mut self.stream.buffer()) {

                    Ok(_) => {

                        println!("Worker finished reading and writing data");

                    },

                    Err(err) => {

                        println!("Worker failed to write data: {}", err);

                    }

                }

            },

            Err(err) => {

                println!("Worker failed to read data: {}", err);

            }

        }

        Poll::Ready(())

    }

}


async fn main() {

    let mut proxy_stream = TcpStream::connect(format!("{}:{}", PROXY_HOST, PROXY_PORT))?;

    let proxy_listener = TcpListener::bind("127.0.0.1:8000")?;

    let mut workers = Vec::new();


    for _ in 0..10 {

        let mut worker = Worker::new(proxy_stream);

        let task = spawn(move || worker.run());

        workers.push(task);

    }


    loop {

        let (socket, _) = proxy_listener.accept()?;


        for worker in workers {

            let task = worker.clone();

            let mut conn = worker.stream;

            if let Ok(conn) = conn {

                task.detach().join();

                proxy_stream = TcpStream::connect(format!("{}:{}", PROXY_HOST, PROXY_PORT))?;

            }

        }

    }

}


async fn run(self: &mut Worker) {

    self.stream.read_to_string(&mut self.stream.buffer())?;

    let url = format!("{}={}", URL, self.stream.buffer().string().trim());

    self.stream.write_to(&url, &mut self.stream.buffer())?;

}

```


步驟如下:


1. 引入所需的 Rust 庫,包括 async-std、std 和 io。

2. 定義一個 Worker 結構體,它有一個 TcpStream 物件作為成員。

3. 實現 Worker 的 Future 和 poll 方法。poll 方法用於處理網路請求,並將結果寫入 URL 地址。

4. 在 main 函式中,建立一個 TcpListener 物件,並使用它建立多個 Worker 執行緒。

5. 在 main 函式中,迴圈監聽連線請求。每當有新的連線請求時,都會建立一個新的 Worker 執行緒,並將其新增到 workers 列表中。

6. 在 main 函式中,當所有的 Worker 執行緒都執行完畢後,退出迴圈。對於每個 Worker 執行緒,都會嘗試將其連線與代理伺服器斷開,並重新連線到代理伺服器。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70032566/viewspace-2993620/,如需轉載,請註明出處,否則將追究法律責任。

相關文章