Home  >  Article  >  Backend Development  >  Detailed explanation of examples of thread pool multi-thread crawler function implemented by php and python

Detailed explanation of examples of thread pool multi-thread crawler function implemented by php and python

墨辰丷
墨辰丷Original
2018-06-01 09:57:462472browse

This article mainly introduces the thread pool multi-thread crawler function implemented by php and python, and analyzes the complete implementation method of the thread pool multi-thread crawler implemented by php and python in the form of examples. Friends in need can refer to it

Multi-threaded crawlers can be used to crawl content. This can improve performance. Here we look at examples of multi-threaded crawlers in php and python thread pools. The code is as follows:

php example

<?php
class Connect extends Worker //worker模式
{
public function __construct()
{
}
public function getConnection()
{
if (!self::$ch)
{
self::$ch = curl_init();
curl_setopt(self::$ch, CURLOPT_TIMEOUT, 2);
curl_setopt(self::$ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt(self::$ch, CURLOPT_HEADER, 0);
curl_setopt(self::$ch, CURLOPT_NOSIGNAL, true);
curl_setopt(self::$ch, CURLOPT_USERAGENT, "Firefox");
curl_setopt(self::$ch, CURLOPT_FOLLOWLOCATION, 1);
}
/* do some exception/error stuff here maybe */
return self::$ch;
}
public function closeConnection()
{
curl_close(self::$ch);
}
/**
* Note that the link is stored statically, which for pthreads, means thread local
* */
protected static $ch;
}
class Query extends Threaded
{
public function __construct($url)
{
$this->url = $url;
}
public function run()
{
$ch = $this->worker->getConnection();
curl_setopt($ch, CURLOPT_URL, $this->url);
$page = curl_exec($ch);
$info = curl_getinfo($ch);
$error = curl_error($ch);
$this->deal_data($this->url, $page, $info, $error);
$this->result = $page;
}
function deal_data($url, $page, $info, $error)
{
$parts = explode(".", $url);
$id = $parts[1];
if ($info[&#39;http_code&#39;] != 200)
{
$this->show_msg($id, $error);
} else
{
$this->show_msg($id, "OK");
}
}
function show_msg($id, $msg)
{
echo $id."\t$msg\n";
}
public function getResult()
{
return $this->result;
}
protected $url;
protected $result;
}
function check_urls_multi_pthreads()
{
global $check_urls; //定义抓取的连接
$check_urls = array( &#39;http://xxx.com&#39; => "xx网",);
$pool = new Pool(10, "Connect", array()); //建立10个线程池
foreach ($check_urls as $url => $name)
{
$pool->submit(new Query($url));
}
$pool->shutdown();
}
check_urls_multi_pthreads();
python 多线程
def handle(sid)://这个方法内执行爬虫数据处理
pass
class MyThread(Thread):
"""docstring for ClassName"""
def __init__(self, sid):
Thread.__init__(self)
self.sid = sid
def run():
handle(self.sid)
threads = []
for i in xrange(1,11):
t = MyThread(i)
threads.append(t)
t.start()
for t in threads:
t.join()

python thread pool crawler:

from queue import Queue
from threading import Thread, Lock
import urllib.parse
import socket
import re
import time
seen_urls = set([&#39;/&#39;])
lock = Lock()
class Fetcher(Thread):
  def __init__(self, tasks):
    Thread.__init__(self)
    self.tasks = tasks
    self.daemon = True
    self.start()
  def run(self):
    while True:
      url = self.tasks.get()
      print(url)
      sock = socket.socket()
      sock.connect((&#39;localhost&#39;, 3000))
      get = &#39;GET {} HTTP/1.0\r\nHost: localhost\r\n\r\n&#39;.format(url)
      sock.send(get.encode(&#39;ascii&#39;))
      response = b&#39;&#39;
      chunk = sock.recv(4096)
      while chunk:
        response += chunk
        chunk = sock.recv(4096)
      links = self.parse_links(url, response)
      lock.acquire()
      for link in links.difference(seen_urls):
        self.tasks.put(link)
      seen_urls.update(links)
      lock.release()
      self.tasks.task_done()
  def parse_links(self, fetched_url, response):
    if not response:
      print(&#39;error: {}&#39;.format(fetched_url))
      return set()
    if not self._is_html(response):
      return set()
    urls = set(re.findall(r&#39;&#39;&#39;(?i)href=["&#39;]?([^\s"&#39;<>]+)&#39;&#39;&#39;,
               self.body(response)))
    links = set()
    for url in urls:
      normalized = urllib.parse.urljoin(fetched_url, url)
      parts = urllib.parse.urlparse(normalized)
      if parts.scheme not in (&#39;&#39;, &#39;http&#39;, &#39;https&#39;):
        continue
      host, port = urllib.parse.splitport(parts.netloc)
      if host and host.lower() not in (&#39;localhost&#39;):
        continue
      defragmented, frag = urllib.parse.urldefrag(parts.path)
      links.add(defragmented)
    return links
  def body(self, response):
    body = response.split(b&#39;\r\n\r\n&#39;, 1)[1]
    return body.decode(&#39;utf-8&#39;)
  def _is_html(self, response):
    head, body = response.split(b&#39;\r\n\r\n&#39;, 1)
    headers = dict(h.split(&#39;: &#39;) for h in head.decode().split(&#39;\r\n&#39;)[1:])
    return headers.get(&#39;Content-Type&#39;, &#39;&#39;).startswith(&#39;text/html&#39;)
class ThreadPool:
  def __init__(self, num_threads):
    self.tasks = Queue()
    for _ in range(num_threads):
      Fetcher(self.tasks)
  def add_task(self, url):
    self.tasks.put(url)
  def wait_completion(self):
    self.tasks.join()
if __name__ == &#39;__main__&#39;:
  start = time.time()
  pool = ThreadPool(4)
  pool.add_task("/")
  pool.wait_completion()
  print(&#39;{} URLs fetched in {:.1f} seconds&#39;.format(len(seen_urls),time.time() - start))

Summary: The above is The entire content of this article is hoped to be helpful to everyone's study.

Related recommendations:

phpEncapsulated page paging class

Three usesphp namespace method

php_imagick method to achieve retro effect

The above is the detailed content of Detailed explanation of examples of thread pool multi-thread crawler function implemented by php and python. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn