Snooy 类 网页抓取

  1. <?php  
  2. // ============Snoopy 网页抓取======================  
  3.   
  4. // 使用方式:  http://www.itokit.com/2011/1105/72479.html  
  5.   
  6. $snoopy = new Snoopy;   
  7. $url = "http://www.baidu.com";  
  8. $snoopy->fetch($url); //获取所有内容   fetch  
  9. $contents =  $snoopy->results; //显示结果   
  10. echo $contents;  
  11. ?>  
  12.   
  13.   
  14.   
  15.   
  16.   
  17. <?php  
  18. // =================Snoopy.class.php==============  
  19. /************************************************* 
  20.  * 
  21.  * Snoopy - the PHP net client 
  22.  * Author: Monte Ohrt <monte@ohrt.com> 
  23.  * Copyright (c): 1999-2014, all rights reserved 
  24.  * Version: 2.0.0 
  25.  * This library is free software; you can redistribute it and/or 
  26.  * modify it under the terms of the GNU Lesser General Public 
  27.  * License as published by the Free Software Foundation; either 
  28.  * version 2.1 of the License, or (at your option) any later version. 
  29.  * 
  30.  * This library is distributed in the hope that it will be useful, 
  31.  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  32.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  33.  * Lesser General Public License for more details. 
  34.  * 
  35.  * You should have received a copy of the GNU Lesser General Public 
  36.  * License along with this library; if not, write to the Free Software 
  37.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  38.  * 
  39.  * You may contact the author of Snoopy by e-mail at: 
  40.  * monte@ohrt.com 
  41.  * 
  42.  * The latest version of Snoopy can be obtained from: 
  43.  * http://snoopy.sourceforge.net/ 
  44.  *************************************************/  
  45. class Snoopy  
  46. {  
  47.     /**** Public variables ****/  
  48.   
  49.     /* user definable vars */  
  50.   
  51.     var $scheme = 'http'// http or https  
  52.     var $host = "www.php.net"// host name we are connecting to  
  53.     var $port = 80; // port we are connecting to  
  54.     var $proxy_host = ""// proxy host to use  
  55.     var $proxy_port = ""// proxy port to use  
  56.     var $proxy_user = ""// proxy user to use  
  57.     var $proxy_pass = ""// proxy password to use  
  58.   
  59.     var $agent = "Snoopy v2.0.0"// agent we masquerade as  
  60.     var $referer = ""// referer info to pass  
  61.     var $cookies = array(); // array of cookies to pass  
  62.     // $cookies["username"]="joe";  
  63.     var $rawheaders = array(); // array of raw headers to send  
  64.     // $rawheaders["Content-type"]="text/html";  
  65.   
  66.     var $maxredirs = 5; // http redirection depth maximum. 0 = disallow  
  67.     var $lastredirectaddr = ""// contains address of last redirected address  
  68.     var $offsiteok = true; // allows redirection off-site  
  69.     var $maxframes = 0; // frame content depth maximum. 0 = disallow  
  70.     var $expandlinks = true; // expand links to fully qualified URLs.  
  71.     // this only applies to fetchlinks()  
  72.     // submitlinks(), and submittext()  
  73.     var $passcookies = true; // pass set cookies back through redirects  
  74.     // NOTE: this currently does not respect  
  75.     // dates, domains or paths.  
  76.   
  77.     var $user = ""// user for http authentication  
  78.     var $pass = ""// password for http authentication  
  79.   
  80.     // http accept types  
  81.     var $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";  
  82.   
  83.     var $results = ""// where the content is put  
  84.   
  85.     var $error = ""// error messages sent here  
  86.     var $response_code = ""// response code returned from server  
  87.     var $headers = array(); // headers returned from server sent here  
  88.     var $maxlength = 500000; // max return data length (body)  
  89.     var $read_timeout = 0; // timeout on read operations, in seconds  
  90.     // supported only since PHP 4 Beta 4  
  91.     // set to 0 to disallow timeouts  
  92.     var $timed_out = false; // if a read operation timed out  
  93.     var $status = 0; // http request status  
  94.   
  95.     var $temp_dir = "/tmp"// temporary directory that the webserver  
  96.     // has permission to write to.  
  97.     // under Windows, this should be C:\temp  
  98.   
  99.     var $curl_path = false;  
  100.     // deprecated, snoopy no longer uses curl for https requests,  
  101.     // but instead requires the openssl extension.  
  102.   
  103.     // send Accept-encoding: gzip?  
  104.     var $use_gzip = true;  
  105.   
  106.     // file or directory with CA certificates to verify remote host with  
  107.     var $cafile;  
  108.     var $capath;  
  109.   
  110.     /**** Private variables ****/  
  111.   
  112.     var $_maxlinelen = 4096; // max line length (headers)  
  113.   
  114.     var $_httpmethod = "GET"// default http request method  
  115.     var $_httpversion = "HTTP/1.0"// default http request version  
  116.     var $_submit_method = "POST"// default submit method  
  117.     var $_submit_type = "application/x-www-form-urlencoded"// default submit type  
  118.     var $_mime_boundary = ""// MIME boundary for multipart/form-data submit type  
  119.     var $_redirectaddr = false; // will be set if page fetched is a redirect  
  120.     var $_redirectdepth = 0; // increments on an http redirect  
  121.     var $_frameurls = array(); // frame src urls  
  122.     var $_framedepth = 0; // increments on frame depth  
  123.   
  124.     var $_isproxy = false; // set if using a proxy server  
  125.     var $_fp_timeout = 30; // timeout for socket connection  
  126.   
  127.     /*======================================================================*\ 
  128.         Function: fetch 
  129.         Purpose:  fetch the contents of a web page 
  130.                     (and possibly other protocols in the 
  131.                     future like ftp, nntp, gopher, etc.) 
  132.         Input:    $URI  the location of the page to fetch 
  133.         Output:   $this->results  the output text from the fetch 
  134.     \*======================================================================*/  
  135.   
  136.     function fetch($URI)  
  137.     {  
  138.   
  139.         $URI_PARTS = parse_url($URI);  
  140.         if (!empty($URI_PARTS["user"]))  
  141.             $this->user = $URI_PARTS["user"];  
  142.         if (!empty($URI_PARTS["pass"]))  
  143.             $this->pass = $URI_PARTS["pass"];  
  144.         if (empty($URI_PARTS["query"]))  
  145.             $URI_PARTS["query"] = '';  
  146.         if (empty($URI_PARTS["path"]))  
  147.             $URI_PARTS["path"] = '';  
  148.   
  149.         $fp = null;  
  150.   
  151.         switch (strtolower($URI_PARTS["scheme"])) {  
  152.             case "https":  
  153.                 if (!extension_loaded('openssl')) {  
  154.                     trigger_error("openssl extension required for HTTPS", E_USER_ERROR);  
  155.                     exit;  
  156.                 }  
  157.                 $this->port = 443;  
  158.             case "http":  
  159.                 $this->scheme = strtolower($URI_PARTS["scheme"]);  
  160.                 $this->host = $URI_PARTS["host"];  
  161.                 if (!empty($URI_PARTS["port"]))  
  162.                     $this->port = $URI_PARTS["port"];  
  163.                 if ($this->_connect($fp)) {  
  164.                     if ($this->_isproxy) {  
  165.                         // using proxy, send entire URI  
  166.                         $this->_httprequest($URI$fp$URI$this->_httpmethod);  
  167.                     } else {  
  168.                         $path = $URI_PARTS["path"] . ($URI_PARTS["query"] ? "?" . $URI_PARTS["query"] : "");  
  169.                         // no proxy, send only the path  
  170.                         $this->_httprequest($path$fp$URI$this->_httpmethod);  
  171.                     }  
  172.   
  173.                     $this->_disconnect($fp);  
  174.   
  175.                     if ($this->_redirectaddr) {  
  176.                         /* url was redirected, check if we've hit the max depth */  
  177.                         if ($this->maxredirs > $this->_redirectdepth) {  
  178.                             // only follow redirect if it's on this site, or offsiteok is true  
  179.                             if (preg_match("|^https?://" . preg_quote($this->host) . "|i"$this->_redirectaddr) || $this->offsiteok) {  
  180.                                 /* follow the redirect */  
  181.                                 $this->_redirectdepth++;  
  182.                                 $this->lastredirectaddr = $this->_redirectaddr;  
  183.                                 $this->fetch($this->_redirectaddr);  
  184.                             }  
  185.                         }  
  186.                     }  
  187.   
  188.                     if ($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0) {  
  189.                         $frameurls = $this->_frameurls;  
  190.                         $this->_frameurls = array();  
  191.   
  192.                         while (list(, $frameurl) = each($frameurls)) {  
  193.                             if ($this->_framedepth < $this->maxframes) {  
  194.                                 $this->fetch($frameurl);  
  195.                                 $this->_framedepth++;  
  196.                             } else  
  197.                                 break;  
  198.                         }  
  199.                     }  
  200.                 } else {  
  201.                     return false;  
  202.                 }  
  203.                 return $this;  
  204.                 break;  
  205.             default:  
  206.                 // not a valid protocol  
  207.                 $this->error = 'Invalid protocol "' . $URI_PARTS["scheme"] . '"\n';  
  208.                 return false;  
  209.                 break;  
  210.         }  
  211.         return $this;  
  212.     }  
  213.   
  214.     /*======================================================================*\ 
  215.         Function: submit 
  216.         Purpose:  submit an http(s) form 
  217.         Input:    $URI  the location to post the data 
  218.                     $formvars the formvars to use. 
  219.                         format: $formvars["var"] = "val"; 
  220.                     $formfiles  an array of files to submit 
  221.                         format: $formfiles["var"] = "/dir/filename.ext"; 
  222.         Output:   $this->results  the text output from the post 
  223.     \*======================================================================*/  
  224.   
  225.     function submit($URI$formvars = ""$formfiles = "")  
  226.     {  
  227.         unset($postdata);  
  228.   
  229.         $postdata = $this->_prepare_post_body($formvars$formfiles);  
  230.   
  231.         $URI_PARTS = parse_url($URI);  
  232.         if (!empty($URI_PARTS["user"]))  
  233.             $this->user = $URI_PARTS["user"];  
  234.         if (!empty($URI_PARTS["pass"]))  
  235.             $this->pass = $URI_PARTS["pass"];  
  236.         if (empty($URI_PARTS["query"]))  
  237.             $URI_PARTS["query"] = '';  
  238.         if (empty($URI_PARTS["path"]))  
  239.             $URI_PARTS["path"] = '';  
  240.   
  241.         switch (strtolower($URI_PARTS["scheme"])) {  
  242.             case "https":  
  243.                 if (!extension_loaded('openssl')) {  
  244.                     trigger_error("openssl extension required for HTTPS", E_USER_ERROR);  
  245.                     exit;  
  246.                 }  
  247.                 $this->port = 443;  
  248.             case "http":  
  249.                 $this->scheme = strtolower($URI_PARTS["scheme"]);  
  250.                 $this->host = $URI_PARTS["host"];  
  251.                 if (!empty($URI_PARTS["port"]))  
  252.                     $this->port = $URI_PARTS["port"];  
  253.                 if ($this->_connect($fp)) {  
  254.                     if ($this->_isproxy) {  
  255.                         // using proxy, send entire URI  
  256.                         $this->_httprequest($URI$fp$URI$this->_submit_method, $this->_submit_type, $postdata);  
  257.                     } else {  
  258.                         $path = $URI_PARTS["path"] . ($URI_PARTS["query"] ? "?" . $URI_PARTS["query"] : "");  
  259.                         // no proxy, send only the path  
  260.                         $this->_httprequest($path$fp$URI$this->_submit_method, $this->_submit_type, $postdata);  
  261.                     }  
  262.   
  263.                     $this->_disconnect($fp);  
  264.   
  265.                     if ($this->_redirectaddr) {  
  266.                         /* url was redirected, check if we've hit the max depth */  
  267.                         if ($this->maxredirs > $this->_redirectdepth) {  
  268.                             if (!preg_match("|^" . $URI_PARTS["scheme"] . "://|"$this->_redirectaddr))  
  269.                                 $this->_redirectaddr = $this->_expandlinks($this->_redirectaddr, $URI_PARTS["scheme"] . "://" . $URI_PARTS["host"]);  
  270.   
  271.                             // only follow redirect if it's on this site, or offsiteok is true  
  272.                             if (preg_match("|^https?://" . preg_quote($this->host) . "|i"$this->_redirectaddr) || $this->offsiteok) {  
  273.                                 /* follow the redirect */  
  274.                                 $this->_redirectdepth++;  
  275.                                 $this->lastredirectaddr = $this->_redirectaddr;  
  276.                                 if (strpos($this->_redirectaddr, "?") > 0)  
  277.                                     $this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get  
  278.                                 else  
  279.                                     $this->submit($this->_redirectaddr, $formvars$formfiles);  
  280.                             }  
  281.                         }  
  282.                     }  
  283.   
  284.                     if ($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0) {  
  285.                         $frameurls = $this->_frameurls;  
  286.                         $this->_frameurls = array();  
  287.   
  288.                         while (list(, $frameurl) = each($frameurls)) {  
  289.                             if ($this->_framedepth < $this->maxframes) {  
  290.                                 $this->fetch($frameurl);  
  291.                                 $this->_framedepth++;  
  292.                             } else  
  293.                                 break;  
  294.                         }  
  295.                     }  
  296.   
  297.                 } else {  
  298.                     return false;  
  299.                 }  
  300.                 return $this;  
  301.                 break;  
  302.             default:  
  303.                 // not a valid protocol  
  304.                 $this->error = 'Invalid protocol "' . $URI_PARTS["scheme"] . '"\n';  
  305.                 return false;  
  306.                 break;  
  307.         }  
  308.         return $this;  
  309.     }  
  310.   
  311.     /*======================================================================*\ 
  312.         Function: fetchlinks 
  313.         Purpose:  fetch the links from a web page 
  314.         Input:    $URI  where you are fetching from 
  315.         Output:   $this->results  an array of the URLs 
  316.     \*======================================================================*/  
  317.   
  318.     function fetchlinks($URI)  
  319.     {  
  320.         if ($this->fetch($URI) !== false) {  
  321.             if ($this->lastredirectaddr)  
  322.                 $URI = $this->lastredirectaddr;  
  323.             if (is_array($this->results)) {  
  324.                 for ($x = 0; $x < count($this->results); $x++)  
  325.                     $this->results[$x] = $this->_striplinks($this->results[$x]);  
  326.             } else  
  327.                 $this->results = $this->_striplinks($this->results);  
  328.   
  329.             if ($this->expandlinks)  
  330.                 $this->results = $this->_expandlinks($this->results, $URI);  
  331.             return $this;  
  332.         } else  
  333.             return false;  
  334.     }  
  335.   
  336.     /*======================================================================*\ 
  337.         Function: fetchform 
  338.         Purpose:  fetch the form elements from a web page 
  339.         Input:    $URI  where you are fetching from 
  340.         Output:   $this->results  the resulting html form 
  341.     \*======================================================================*/  
  342.   
  343.     function fetchform($URI)  
  344.     {  
  345.   
  346.         if ($this->fetch($URI) !== false) {  
  347.   
  348.             if (is_array($this->results)) {  
  349.                 for ($x = 0; $x < count($this->results); $x++)  
  350.                     $this->results[$x] = $this->_stripform($this->results[$x]);  
  351.             } else  
  352.                 $this->results = $this->_stripform($this->results);  
  353.   
  354.             return $this;  
  355.         } else  
  356.             return false;  
  357.     }  
  358.   
  359.   
  360.     /*======================================================================*\ 
  361.         Function: fetchtext 
  362.         Purpose:  fetch the text from a web page, stripping the links 
  363.         Input:    $URI  where you are fetching from 
  364.         Output:   $this->results  the text from the web page 
  365.     \*======================================================================*/  
  366.   
  367.     function fetchtext($URI)  
  368.     {  
  369.         if ($this->fetch($URI) !== false) {  
  370.             if (is_array($this->results)) {  
  371.                 for ($x = 0; $x < count($this->results); $x++)  
  372.                     $this->results[$x] = $this->_striptext($this->results[$x]);  
  373.             } else  
  374.                 $this->results = $this->_striptext($this->results);  
  375.             return $this;  
  376.         } else  
  377.             return false;  
  378.     }  
  379.   
  380.     /*======================================================================*\ 
  381.         Function: submitlinks 
  382.         Purpose:  grab links from a form submission 
  383.         Input:    $URI  where you are submitting from 
  384.         Output:   $this->results  an array of the links from the post 
  385.     \*======================================================================*/  
  386.   
  387.     function submitlinks($URI$formvars = ""$formfiles = "")  
  388.     {  
  389.         if ($this->submit($URI$formvars$formfiles) !== false) {  
  390.             if ($this->lastredirectaddr)  
  391.                 $URI = $this->lastredirectaddr;  
  392.             if (is_array($this->results)) {  
  393.                 for ($x = 0; $x < count($this->results); $x++) {  
  394.                     $this->results[$x] = $this->_striplinks($this->results[$x]);  
  395.                     if ($this->expandlinks)  
  396.                         $this->results[$x] = $this->_expandlinks($this->results[$x], $URI);  
  397.                 }  
  398.             } else {  
  399.                 $this->results = $this->_striplinks($this->results);  
  400.                 if ($this->expandlinks)  
  401.                     $this->results = $this->_expandlinks($this->results, $URI);  
  402.             }  
  403.             return $this;  
  404.         } else  
  405.             return false;  
  406.     }  
  407.   
  408.     /*======================================================================*\ 
  409.         Function: submittext 
  410.         Purpose:  grab text from a form submission 
  411.         Input:    $URI  where you are submitting from 
  412.         Output:   $this->results  the text from the web page 
  413.     \*======================================================================*/  
  414.   
  415.     function submittext($URI$formvars = ""$formfiles = "")  
  416.     {  
  417.         if ($this->submit($URI$formvars$formfiles) !== false) {  
  418.             if ($this->lastredirectaddr)  
  419.                 $URI = $this->lastredirectaddr;  
  420.             if (is_array($this->results)) {  
  421.                 for ($x = 0; $x < count($this->results); $x++) {  
  422.                     $this->results[$x] = $this->_striptext($this->results[$x]);  
  423.                     if ($this->expandlinks)  
  424.                         $this->results[$x] = $this->_expandlinks($this->results[$x], $URI);  
  425.                 }  
  426.             } else {  
  427.                 $this->results = $this->_striptext($this->results);  
  428.                 if ($this->expandlinks)  
  429.                     $this->results = $this->_expandlinks($this->results, $URI);  
  430.             }  
  431.             return $this;  
  432.         } else  
  433.             return false;  
  434.     }  
  435.   
  436.   
  437.     /*======================================================================*\ 
  438.         Function: set_submit_multipart 
  439.         Purpose:  Set the form submission content type to 
  440.                     multipart/form-data 
  441.     \*======================================================================*/  
  442.     function set_submit_multipart()  
  443.     {  
  444.         $this->_submit_type = "multipart/form-data";  
  445.         return $this;  
  446.     }  
  447.   
  448.   
  449.     /*======================================================================*\ 
  450.         Function: set_submit_normal 
  451.         Purpose:  Set the form submission content type to 
  452.                     application/x-www-form-urlencoded 
  453.     \*======================================================================*/  
  454.     function set_submit_normal()  
  455.     {  
  456.         $this->_submit_type = "application/x-www-form-urlencoded";  
  457.         return $this;  
  458.     }  
  459.   
  460.   
  461.   
  462.   
  463.     /*======================================================================*\ 
  464.         Private functions 
  465.     \*======================================================================*/  
  466.   
  467.   
  468.     /*======================================================================*\ 
  469.         Function: _striplinks 
  470.         Purpose:  strip the hyperlinks from an html document 
  471.         Input:    $document document to strip. 
  472.         Output:   $match    an array of the links 
  473.     \*======================================================================*/  
  474.   
  475.     function _striplinks($document)  
  476.     {  
  477.         preg_match_all("'<\s*a\s.*?href\s*=\s*      # find <a href=  
  478.             ([\"\'])?         # find single or double quote  
  479.             (?(1) (.*?)\\1 | ([^\s\>]+))    # if quote found, match up to next matching  
  480.                           # quote, otherwise match up to next space  
  481.             'isx", $document$links);  
  482.   
  483.   
  484.         // catenate the non-empty matches from the conditional subpattern  
  485.   
  486.         while (list($key$val) = each($links[2])) {  
  487.             if (!empty($val))  
  488.                 $match[] = $val;  
  489.         }  
  490.   
  491.         while (list($key$val) = each($links[3])) {  
  492.             if (!empty($val))  
  493.                 $match[] = $val;  
  494.         }  
  495.   
  496.         // return the links  
  497.         return $match;  
  498.     }  
  499.   
  500.     /*======================================================================*\ 
  501.         Function: _stripform 
  502.         Purpose:  strip the form elements from an html document 
  503.         Input:    $document document to strip. 
  504.         Output:   $match    an array of the links 
  505.     \*======================================================================*/  
  506.   
  507.     function _stripform($document)  
  508.     {  
  509.         preg_match_all("'<\/?(FORM|INPUT|SELECT|TEXTAREA|(OPTION))[^<>]*>(?(2)(.*(?=<\/?(option|select)[^<>]*>[\r\n]*)|(?=[\r\n]*))|(?=[\r\n]*))'Usi"$document$elements);  
  510.   
  511.         // catenate the matches  
  512.         $match = implode("\r\n"$elements[0]);  
  513.   
  514.         // return the links  
  515.         return $match;  
  516.     }  
  517.   
  518.   
  519.     /*======================================================================*\ 
  520.         Function: _striptext 
  521.         Purpose:  strip the text from an html document 
  522.         Input:    $document document to strip. 
  523.         Output:   $text   the resulting text 
  524.     \*======================================================================*/  
  525.   
  526.     function _striptext($document)  
  527.     {  
  528.   
  529.         // I didn't use preg eval (//e) since that is only available in PHP 4.0.  
  530.         // so, list your entities one by one here. I included some of the  
  531.         // more common ones.  
  532.   
  533.         $search = array("'<script[^>]*?>.*?</script>'si"// strip out javascript  
  534.             "'<[\/\!]*?[^<>]*?>'si"// strip out html tags  
  535.             "'([\r\n])[\s]+'"// strip out white space  
  536.             "'&(quot|#34|#034|#x22);'i"// replace html entities  
  537.             "'&(amp|#38|#038|#x26);'i"// added hexadecimal values  
  538.             "'&(lt|#60|#060|#x3c);'i",  
  539.             "'&(gt|#62|#062|#x3e);'i",  
  540.             "'&(nbsp|#160|#xa0);'i",  
  541.             "'&(iexcl|#161);'i",  
  542.             "'&(cent|#162);'i",  
  543.             "'&(pound|#163);'i",  
  544.             "'&(copy|#169);'i",  
  545.             "'&(reg|#174);'i",  
  546.             "'&(deg|#176);'i",  
  547.             "'&(#39|#039|#x27);'",  
  548.             "'&(euro|#8364);'i"// europe  
  549.             "'&a(uml|UML);'"// german  
  550.             "'&o(uml|UML);'",  
  551.             "'&u(uml|UML);'",  
  552.             "'&A(uml|UML);'",  
  553.             "'&O(uml|UML);'",  
  554.             "'&U(uml|UML);'",  
  555.             "'ß'i",  
  556.         );  
  557.         $replace = array("",  
  558.             "",  
  559.             "\\1",  
  560.             "\"",  
  561.             "&",  
  562.             "<",  
  563.             ">",  
  564.             " ",  
  565.             chr(161),  
  566.             chr(162),  
  567.             chr(163),  
  568.             chr(169),  
  569.             chr(174),  
  570.             chr(176),  
  571.             chr(39),  
  572.             chr(128),  
  573.             "ä",  
  574.             "ö",  
  575.             "ü",  
  576.             "Ä",  
  577.             "Ö",  
  578.             "Ü",  
  579.             "ß",  
  580.         );  
  581.   
  582.         $text = preg_replace($search$replace$document);  
  583.   
  584.         return $text;  
  585.     }  
  586.   
  587.     /*======================================================================*\ 
  588.         Function: _expandlinks 
  589.         Purpose:  expand each link into a fully qualified URL 
  590.         Input:    $links      the links to qualify 
  591.                     $URI      the full URI to get the base from 
  592.         Output:   $expandedLinks  the expanded links 
  593.     \*======================================================================*/  
  594.   
  595.     function _expandlinks($links$URI)  
  596.     {  
  597.   
  598.         preg_match("/^[^\?]+/"$URI$match);  
  599.   
  600.         $match = preg_replace("|/[^\/\.]+\.[^\/\.]+$|"""$match[0]);  
  601.         $match = preg_replace("|/$|"""$match);  
  602.         $match_part = parse_url($match);  
  603.         $match_root =  
  604.             $match_part["scheme"] . "://" . $match_part["host"];  
  605.   
  606.         $search = array("|^http://" . preg_quote($this->host) . "|i",  
  607.             "|^(\/)|i",  
  608.             "|^(?!http://)(?!mailto:)|i",  
  609.             "|/\./|",  
  610.             "|/[^\/]+/\.\./|"  
  611.         );  
  612.   
  613.         $replace = array("",  
  614.             $match_root . "/",  
  615.             $match . "/",  
  616.             "/",  
  617.             "/"  
  618.         );  
  619.   
  620.         $expandedLinks = preg_replace($search$replace$links);  
  621.   
  622.         return $expandedLinks;  
  623.     }  
  624.   
  625.     /*======================================================================*\ 
  626.         Function: _httprequest 
  627.         Purpose:  go get the http(s) data from the server 
  628.         Input:    $url    the url to fetch 
  629.                     $fp     the current open file pointer 
  630.                     $URI    the full URI 
  631.                     $body   body contents to send if any (POST) 
  632.         Output: 
  633.     \*======================================================================*/  
  634.   
  635.     function _httprequest($url$fp$URI$http_method$content_type = ""$body = "")  
  636.     {  
  637.         $cookie_headers = '';  
  638.         if ($this->passcookies && $this->_redirectaddr)  
  639.             $this->setcookies();  
  640.   
  641.         $URI_PARTS = parse_url($URI);  
  642.         if (empty($url))  
  643.             $url = "/";  
  644.         $headers = $http_method . " " . $url . " " . $this->_httpversion . "\r\n";  
  645.         if (!empty($this->host) && !isset($this->rawheaders['Host'])) {  
  646.             $headers .= "Host: " . $this->host;  
  647.             if (!empty($this->port) && $this->port != '80')  
  648.                 $headers .= ":" . $this->port;  
  649.             $headers .= "\r\n";  
  650.         }  
  651.         if (!empty($this->agent))  
  652.             $headers .= "User-Agent: " . $this->agent . "\r\n";  
  653.         if (!empty($this->accept))  
  654.             $headers .= "Accept: " . $this->accept . "\r\n";  
  655.         if ($this->use_gzip) {  
  656.             // make sure PHP was built with --with-zlib  
  657.             // and we can handle gzipp'ed data  
  658.             if (function_exists('gzinflate')) {  
  659.                 $headers .= "Accept-encoding: gzip\r\n";  
  660.             } else {  
  661.                 trigger_error(  
  662.                     "use_gzip is on, but PHP was built without zlib support." .  
  663.                     "  Requesting file(s) without gzip encoding.",  
  664.                     E_USER_NOTICE);  
  665.             }  
  666.         }  
  667.         if (!empty($this->referer))  
  668.             $headers .= "Referer: " . $this->referer . "\r\n";  
  669.         if (!empty($this->cookies)) {  
  670.             if (!is_array($this->cookies))  
  671.                 $this->cookies = (array)$this->cookies;  
  672.   
  673.             reset($this->cookies);  
  674.             if (count($this->cookies) > 0) {  
  675.                 $cookie_headers .= 'Cookie: ';  
  676.                 foreach ($this->cookies as $cookieKey => $cookieVal) {  
  677.                     $cookie_headers .= $cookieKey . "=" . urlencode($cookieVal) . "; ";  
  678.                 }  
  679.                 $headers .= substr($cookie_headers, 0, -2) . "\r\n";  
  680.             }  
  681.         }  
  682.         if (!empty($this->rawheaders)) {  
  683.             if (!is_array($this->rawheaders))  
  684.                 $this->rawheaders = (array)$this->rawheaders;  
  685.             while (list($headerKey$headerVal) = each($this->rawheaders))  
  686.                 $headers .= $headerKey . ": " . $headerVal . "\r\n";  
  687.         }  
  688.         if (!empty($content_type)) {  
  689.             $headers .= "Content-type: $content_type";  
  690.             if ($content_type == "multipart/form-data")  
  691.                 $headers .= "; boundary=" . $this->_mime_boundary;  
  692.             $headers .= "\r\n";  
  693.         }  
  694.         if (!empty($body))  
  695.             $headers .= "Content-length: " . strlen($body) . "\r\n";  
  696.         if (!empty($this->user) || !empty($this->pass))  
  697.             $headers .= "Authorization: Basic " . base64_encode($this->user . ":" . $this->pass) . "\r\n";  
  698.   
  699.         //add proxy auth headers  
  700.         if (!empty($this->proxy_user))  
  701.             $headers .= 'Proxy-Authorization: ' . 'Basic ' . base64_encode($this->proxy_user . ':' . $this->proxy_pass) . "\r\n";  
  702.   
  703.   
  704.         $headers .= "\r\n";  
  705.   
  706.         // set the read timeout if needed  
  707.         if ($this->read_timeout > 0)  
  708.             socket_set_timeout($fp$this->read_timeout);  
  709.         $this->timed_out = false;  
  710.   
  711.         fwrite($fp$headers . $bodystrlen($headers . $body));  
  712.   
  713.         $this->_redirectaddr = false;  
  714.         unset($this->headers);  
  715.   
  716.         // content was returned gzip encoded?  
  717.         $is_gzipped = false;  
  718.   
  719.         while ($currentHeader = fgets($fp$this->_maxlinelen)) {  
  720.             if ($this->read_timeout > 0 && $this->_check_timeout($fp)) {  
  721.                 $this->status = -100;  
  722.                 return false;  
  723.             }  
  724.   
  725.             if ($currentHeader == "\r\n")  
  726.                 break;  
  727.   
  728.             // if a header begins with Location: or URI:, set the redirect  
  729.             if (preg_match("/^(Location:|URI:)/i"$currentHeader)) {  
  730.                 // get URL portion of the redirect  
  731.                 preg_match("/^(Location:|URI:)[ ]+(.*)/i"chop($currentHeader), $matches);  
  732.                 // look for :// in the Location header to see if hostname is included  
  733.                 if (!preg_match("|\:\/\/|"$matches[2])) {  
  734.                     // no host in the path, so prepend  
  735.                     $this->_redirectaddr = $URI_PARTS["scheme"] . "://" . $this->host . ":" . $this->port;  
  736.                     // eliminate double slash  
  737.                     if (!preg_match("|^/|"$matches[2]))  
  738.                         $this->_redirectaddr .= "/" . $matches[2];  
  739.                     else  
  740.                         $this->_redirectaddr .= $matches[2];  
  741.                 } else  
  742.                     $this->_redirectaddr = $matches[2];  
  743.             }  
  744.   
  745.             if (preg_match("|^HTTP/|"$currentHeader)) {  
  746.                 if (preg_match("|^HTTP/[^\s]*\s(.*?)\s|"$currentHeader$status)) {  
  747.                     $this->status = $status[1];  
  748.                 }  
  749.                 $this->response_code = $currentHeader;  
  750.             }  
  751.   
  752.             if (preg_match("/Content-Encoding: gzip/"$currentHeader)) {  
  753.                 $is_gzipped = true;  
  754.             }  
  755.   
  756.             $this->headers[] = $currentHeader;  
  757.         }  
  758.   
  759.         $results = '';  
  760.         do {  
  761.             $_data = fread($fp$this->maxlength);  
  762.             if (strlen($_data) == 0) {  
  763.                 break;  
  764.             }  
  765.             $results .= $_data;  
  766.         } while (true);  
  767.   
  768.         // gunzip  
  769.         if ($is_gzipped) {  
  770.             // per http://www.php.net/manual/en/function.gzencode.php  
  771.             $results = substr($results, 10);  
  772.             $results = gzinflate($results);  
  773.         }  
  774.   
  775.         if ($this->read_timeout > 0 && $this->_check_timeout($fp)) {  
  776.             $this->status = -100;  
  777.             return false;  
  778.         }  
  779.   
  780.         // check if there is a a redirect meta tag  
  781.   
  782.         if (preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]*URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i"$results$match)) {  
  783.             $this->_redirectaddr = $this->_expandlinks($match[1], $URI);  
  784.         }  
  785.   
  786.         // have we hit our frame depth and is there frame src to fetch?  
  787.         if (($this->_framedepth < $this->maxframes) && preg_match_all("'<frame\s+.*src[\s]*=[\'\"]?([^\'\"\>]+)'i"$results$match)) {  
  788.             $this->results[] = $results;  
  789.             for ($x = 0; $x < count($match[1]); $x++)  
  790.                 $this->_frameurls[] = $this->_expandlinks($match[1][$x], $URI_PARTS["scheme"] . "://" . $this->host);  
  791.         } // have we already fetched framed content?  
  792.         elseif (is_array($this->results))  
  793.             $this->results[] = $results;  
  794.         // no framed content  
  795.         else  
  796.             $this->results = $results;  
  797.   
  798.         return $this;  
  799.     }  
  800.   
  801.     /*======================================================================*\ 
  802.         Function: setcookies() 
  803.         Purpose:  set cookies for a redirection 
  804.     \*======================================================================*/  
  805.   
  806.     function setcookies()  
  807.     {  
  808.         for ($x = 0; $x < count($this->headers); $x++) {  
  809.             if (preg_match('/^set-cookie:[\s]+([^=]+)=([^;]+)/i'$this->headers[$x], $match))  
  810.                 $this->cookies[$match[1]] = urldecode($match[2]);  
  811.         }  
  812.         return $this;  
  813.     }  
  814.   
  815.   
  816.     /*======================================================================*\ 
  817.         Function: _check_timeout 
  818.         Purpose:  checks whether timeout has occurred 
  819.         Input:    $fp file pointer 
  820.     \*======================================================================*/  
  821.   
  822.     function _check_timeout($fp)  
  823.     {  
  824.         if ($this->read_timeout > 0) {  
  825.             $fp_status = socket_get_status($fp);  
  826.             if ($fp_status["timed_out"]) {  
  827.                 $this->timed_out = true;  
  828.                 return true;  
  829.             }  
  830.         }  
  831.         return false;  
  832.     }  
  833.   
  834.     /*======================================================================*\ 
  835.         Function: _connect 
  836.         Purpose:  make a socket connection 
  837.         Input:    $fp file pointer 
  838.     \*======================================================================*/  
  839.   
  840.     function _connect(&$fp)  
  841.     {  
  842.         if (!empty($this->proxy_host) && !empty($this->proxy_port)) {  
  843.             $this->_isproxy = true;  
  844.   
  845.             $host = $this->proxy_host;  
  846.             $port = $this->proxy_port;  
  847.   
  848.             if ($this->scheme == 'https') {  
  849.                 trigger_error("HTTPS connections over proxy are currently not supported", E_USER_ERROR);  
  850.                 exit;  
  851.             }  
  852.         } else {  
  853.             $host = $this->host;  
  854.             $port = $this->port;  
  855.         }  
  856.   
  857.         $this->status = 0;  
  858.   
  859.         $context_opts = array();  
  860.   
  861.         if ($this->scheme == 'https') {  
  862.             // if cafile or capath is specified, enable certificate  
  863.             // verification (including name checks)  
  864.             if (isset($this->cafile) || isset($this->capath)) {  
  865.                 $context_opts['ssl'] = array(  
  866.                     'verify_peer' => true,  
  867.                     'CN_match' => $this->host,  
  868.                     'disable_compression' => true,  
  869.                 );  
  870.   
  871.                 if (isset($this->cafile))  
  872.                     $context_opts['ssl']['cafile'] = $this->cafile;  
  873.                 if (isset($this->capath))  
  874.                     $context_opts['ssl']['capath'] = $this->capath;  
  875.             }  
  876.                       
  877.             $host = 'ssl://' . $host;  
  878.         }  
  879.   
  880.         $context = stream_context_create($context_opts);  
  881.   
  882.         if (version_compare(PHP_VERSION, '5.0.0''>')) {  
  883.             if($this->scheme == 'http')  
  884.                 $host = "tcp://" . $host;  
  885.             $fp = stream_socket_client(  
  886.                 "$host:$port",  
  887.                 $errno,  
  888.                 $errmsg,  
  889.                 $this->_fp_timeout,  
  890.                 STREAM_CLIENT_CONNECT,  
  891.                 $context);  
  892.         } else {  
  893.             $fp = fsockopen(  
  894.                 $host,  
  895.                 $port,  
  896.                 $errno,  
  897.                 $errstr,  
  898.                 $this->_fp_timeout,  
  899.                 $context);  
  900.         }  
  901.   
  902.         if ($fp) {  
  903.             // socket connection succeeded  
  904.             return true;  
  905.         } else {  
  906.             // socket connection failed  
  907.             $this->status = $errno;  
  908.             switch ($errno) {  
  909.                 case -3:  
  910.                     $this->error = "socket creation failed (-3)";  
  911.                 case -4:  
  912.                     $this->error = "dns lookup failure (-4)";  
  913.                 case -5:  
  914.                     $this->error = "connection refused or timed out (-5)";  
  915.                 default:  
  916.                     $this->error = "connection failed (" . $errno . ")";  
  917.             }  
  918.             return false;  
  919.         }  
  920.     }  
  921.   
  922.     /*======================================================================*\ 
  923.         Function: _disconnect 
  924.         Purpose:  disconnect a socket connection 
  925.         Input:    $fp file pointer 
  926.     \*======================================================================*/  
  927.   
  928.     function _disconnect($fp)  
  929.     {  
  930.         return (fclose($fp));  
  931.     }  
  932.   
  933.   
  934.     /*======================================================================*\ 
  935.         Function: _prepare_post_body 
  936.         Purpose:  Prepare post body according to encoding type 
  937.         Input:    $formvars  - form variables 
  938.                     $formfiles - form upload files 
  939.         Output:   post body 
  940.     \*======================================================================*/  
  941.   
  942.     function _prepare_post_body($formvars$formfiles)  
  943.     {  
  944.         settype($formvars"array");  
  945.         settype($formfiles"array");  
  946.         $postdata = '';  
  947.   
  948.         if (count($formvars) == 0 && count($formfiles) == 0)  
  949.             return;  
  950.   
  951.         switch ($this->_submit_type) {  
  952.             case "application/x-www-form-urlencoded":  
  953.                 reset($formvars);  
  954.                 while (list($key$val) = each($formvars)) {  
  955.                     if (is_array($val) || is_object($val)) {  
  956.                         while (list($cur_key$cur_val) = each($val)) {  
  957.                             $postdata .= urlencode($key) . "[]=" . urlencode($cur_val) . "&";  
  958.                         }  
  959.                     } else  
  960.                         $postdata .= urlencode($key) . "=" . urlencode($val) . "&";  
  961.                 }  
  962.                 break;  
  963.   
  964.             case "multipart/form-data":  
  965.                 $this->_mime_boundary = "Snoopy" . md5(uniqid(microtime()));  
  966.   
  967.                 reset($formvars);  
  968.                 while (list($key$val) = each($formvars)) {  
  969.                     if (is_array($val) || is_object($val)) {  
  970.                         while (list($cur_key$cur_val) = each($val)) {  
  971.                             $postdata .= "--" . $this->_mime_boundary . "\r\n";  
  972.                             $postdata .= "Content-Disposition: form-data; name=\"$key
    \"\r\n\r\n";  
  973.                             $postdata .= "$cur_val\r\n";  
  974.                         }  
  975.                     } else {  
  976.                         $postdata .= "--" . $this->_mime_boundary . "\r\n";  
  977.                         $postdata .= "Content-Disposition: form-data; name=\"$key\"\r\n\r\n";  
  978.                         $postdata .= "$val\r\n";  
  979.                     }  
  980.                 }  
  981.   
  982.                 reset($formfiles);  
  983.                 while (list($field_name$file_names) = each($formfiles)) {  
  984.                     settype($file_names"array");  
  985.                     while (list(, $file_name) = each($file_names)) {  
  986.                         if (!is_readable($file_name)) continue;  
  987.   
  988.                         $fp = fopen($file_name"r");  
  989.                         $file_content = fread($fpfilesize($file_name));  
  990.                         fclose($fp);  
  991.                         $base_name = basename($file_name);  
  992.   
  993.                         $postdata .= "--" . $this->_mime_boundary . "\r\n";  
  994.                         $postdata .= "Content-Disposition: form-data; name=\"$field_name\"; filename=\"$base_name\"\r\n\r\n";  
  995.                         $postdata .= "$file_content\r\n";  
  996.                     }  
  997.                 }  
  998.                 $postdata .= "--" . $this->_mime_boundary . "--\r\n";  
  999.                 break;  
  1000.         }  
  1001.   
  1002.         return $postdata;  
  1003.     }  
  1004.   
  1005.     /*======================================================================*\ 
  1006.     Function: getResults 
  1007.     Purpose:  return the results of a request 
  1008.     Output:   string results 
  1009.     \*======================================================================*/  
  1010.   
  1011.     function getResults()  
  1012.     {  
  1013.         return $this->results;  
  1014.     }  
  1015. }  
  1016.   
  1017. ?>
基于数据挖掘的音乐推荐系统设计与实现 需要一个代码说明,不需要论文 采用python语言,django框架,mysql数据库开发 编程环境:pycharm,mysql8.0 系统分为前台+后台模式开发 网站前台: 用户注册, 登录 搜索音乐,音乐欣赏(可以在线进行播放) 用户登陆时选择相关感兴趣的音乐风格 音乐收藏 音乐推荐算法:(重点) 本课题需要大量用户行为(如播放记录、收藏列表)、音乐特征(如音频特征、歌曲元数据)等数据 (1)根据用户之间相似性或关联性,给一个用户推荐与其相似或有关联的其他用户所感兴趣的音乐; (2)根据音乐之间的相似性或关联性,给一个用户推荐与其感兴趣的音乐相似或有关联的其他音乐。 基于用户的推荐和基于物品的推荐 其中基于用户的推荐是基于用户的相似度找出相似相似用户,然后向目标用户推荐其相似用户喜欢的东西(和你似的人也喜欢**东西); 而基于物品的推荐是基于物品的相似度找出相似的物品做推荐(喜欢该音乐的人还喜欢了**音乐); 管理员 管理员信息管理 注册用户管理,审核 音乐爬虫(爬虫方式爬取网站音乐数据) 音乐信息管理(上传歌曲MP3,以便前台播放) 音乐收藏管理 用户 用户资料修改 我的音乐收藏 完整前后端源码,部署后可正常运行! 环境说明 开发语言:python后端 python版本:3.7 数据库:mysql 5.7+ 数据库工具:Navicat11+ 开发软件:pycharm
MPU6050是一款广泛应用在无人机、机器人和运动设备中的六轴姿态传感器,它集成了三轴陀螺仪和三轴加速度计。这款传感器能够实时监测并提供设备的角速度和线性加速度数据,对于理解物体的动态运动状态至关重要。在Arduino平台上,通过特定的库文件可以方便地与MPU6050进行通信,获取并解析传感器数据。 `MPU6050.cpp`和`MPU6050.h`是Arduino库的关键组成部分。`MPU6050.h`是头文件,包含了定义传感器接口和函数声明。它定义了`MPU6050`,该包含了初始化传感器、读取数据等方法。例如,`begin()`函数用于设置传感器的工作模式和I2C地址,`getAcceleration()`和`getGyroscope()`则分别用于获取加速度和角速度数据。 在Arduino项目中,首先需要包含`MPU6050.h`头文件,然后创建`MPU6050`对象,并调用`begin()`函数初始化传感器。之后,可以通过循环调用`getAcceleration()`和`getGyroscope()`来不断更新传感器读数。为了处理这些原始数据,通常还需要进行校准和滤波,以消除噪声和漂移。 I2C通信协议是MPU6050与Arduino交互的基础,它是一种低引脚数的串行通信协议,允许多个设备共享一对数据线。Arduino板上的Wire库提供了I2C通信的底层支持,使得用户无需深入了解通信细节,就能方便地与MPU6050交互。 MPU6050传感器的数据包括加速度(X、Y、Z轴)和角速度(同样为X、Y、Z轴)。加速度数据可以用来计算物体的静态位置和动态运动,而角速度数据则能反映物体转动的速度。结合这两个数据,可以进一步计算出物体的姿态(如角度和角速度变化)。 在嵌入式开发领域,特别是使用STM32微控制器时,也可以找到似的库来驱动MPU6050。STM32通常具有更强大的处理能力和更多的GPIO口,可以实现更复杂的控制算法。然而,基本的传感器操作流程和数据处理原理与Arduino平台相似。 在实际应用中,除了基本的传感器读取,还可能涉及到温度补偿、低功耗模式设置、DMP(数字运动处理器)功能的利用等高级特性。DMP可以帮助处理传感器数据,实现更高级的运动估计,减轻主控制器的计算负担。 MPU6050是一个强大的六轴传感器,广泛应用于各种需要实时运动追踪的项目中。通过 Arduino 或 STM32 的库文件,开发者可以轻松地与传感器交互,获取并处理数据,实现各种创新应用。博客和其他开源资源是学习和解决问题的重要途径,通过这些资源,开发者可以获得关于MPU6050的详细信息和实践指南
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值