목차
PHP开发:使用PHP抓取百万知乎用户以及知识点札记
백엔드 개발 PHP 튜토리얼 PHP开发:使用PHP抓取百万知乎用户以及知识点札记_PHP教程

PHP开发:使用PHP抓取百万知乎用户以及知识点札记_PHP教程

Jul 12, 2016 am 09:07 AM
기다

PHP开发:使用PHP抓取百万知乎用户以及知识点札记

代码托管地址:https://github.com/hhqcontinue/zhihuSpider

开发前的准备

安装Linux系统Ubuntu14.04),在VMWare虚拟机下安装一个Ubuntu;

安装PHP5.6或以上版本;

安装curl、pcntl扩展。 

使用PHP的curl扩展抓取页面数据

PHP的curl扩展是PHP支持的允许你与各种服务器使用各种类型的协议进行连接和通信的库。

本程序是抓取知乎的用户数据,要能访问用户个人页面,需要用户登录后的才能访问。当我们在浏览器的页面中点击一个用户头像链接进入用户个人中心页面 的时候,之所以能够看到用户的信息,是因为在点击链接的时候,浏览器帮你将本地的cookie带上一齐提交到新的页面,所以你就能进入到用户的个人中心页 面。因此实现访问个人页面之前需要先获得用户的cookie信息,然后在每次curl请求的时候带上cookie信息。在获取cookie信息方面,我是 用了自己的cookie,在页面中可以看到自己的cookie信息:

一个个地复制,以"__utma=?;__utmb=?;"这样的形式组成一个cookie字符串。接下来就可以使用该cookie字符串来发送请求。

初始的示例:

<ol class="dp-j"><li class="alt"><span><span>$url = </span><span class="string">'http://www.zhihu.com/people/mora-hu/about'</span><span>; //此处mora-hu代表用户ID </span></span></li><li><span>    $ch = curl_init($url); <span class="comment">//初始化会话</span><span> </span></span></li><li class="alt"><span>    curl_setopt($ch, CURLOPT_HEADER, <span class="number">0</span><span>); </span></span></li><li><span>    curl_setopt($ch, CURLOPT_COOKIE, $<span class="keyword">this</span><span>->config_arr[</span><span class="string">'user_cookie'</span><span>]);  </span><span class="comment">//设置请求COOKIE</span><span> </span></span></li><li class="alt"><span>    curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER[<span class="string">'HTTP_USER_AGENT'</span><span>]); </span></span></li><li><span>    curl_setopt($ch, CURLOPT_RETURNTRANSFER, <span class="number">1</span><span>);  </span><span class="comment">//将curl_exec()获取的信息以文件流的形式返回,而不是直接输出。</span><span> </span></span></li><li class="alt"><span>    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, <span class="number">1</span><span>);   </span></span></li><li><span>    $result = curl_exec($ch); </span></li><li class="alt"><span>    <span class="keyword">return</span><span> $result;  </span><span class="comment">//抓取的结果</span><span> </span></span></li></ol>
로그인 후 복사

运行上面的代码可以获得mora-hu用户的个人中心页面。利用该结果再使用正则表达式对页面进行处理,就能获取到姓名,性别等所需要抓取的信息。

图片防盗链

在对返回结果进行正则处理后输出个人信息的时候,发现在页面中输出用户头像时无法打开。经过查阅资料得知,是因为知乎对图片做了防盗链处理。解决方案就是请求图片的时候在请求头里伪造一个referer。

在使用正则表达式获取到图片的链接之后,再发一次请求,这时候带上图片请求的来源,说明该请求来自知乎网站的转发。具体例子如下:

<ol class="dp-j"><li class="alt"><span><span>function getImg($url, $u_id) </span></span></li><li><span>{ </span></li><li class="alt"><span>    <span class="keyword">if</span><span> (file_exists(</span><span class="string">'./images/'</span><span> . $u_id . </span><span class="string">".jpg"</span><span>)) </span></span></li><li><span>    { </span></li><li class="alt"><span>        <span class="keyword">return</span><span> </span><span class="string">"images/$u_id"</span><span> . </span><span class="string">'.jpg'</span><span>; </span></span></li><li><span>    } </span></li><li class="alt"><span>    <span class="keyword">if</span><span> (empty($url)) </span></span></li><li><span>    { </span></li><li class="alt"><span>        <span class="keyword">return</span><span> </span><span class="string">''</span><span>; </span></span></li><li><span>    } </span></li><li class="alt"><span>    $context_options = array(   </span></li><li><span>        <span class="string">'http'</span><span> =>   </span></span></li><li class="alt"><span>        array( </span></li><li><span>            <span class="string">'header'</span><span> => </span><span class="string">"Referer:http://www.zhihu.com"</span><span>//带上referer参数  </span></span></li><li class="alt"><span>    ) </span></li><li><span>); </span></li><li class="alt"><span>       </span></li><li><span>    $context = stream_context_create($context_options);   </span></li><li class="alt"><span>    $img = file_get_contents(<span class="string">'http:'</span><span> . $url, FALSE, $context); </span></span></li><li><span>    file_put_contents(<span class="string">'./images/'</span><span> . $u_id . </span><span class="string">".jpg"</span><span>, $img); </span></span></li><li class="alt"><span>    <span class="keyword">return</span><span> </span><span class="string">"images/$u_id"</span><span> . </span><span class="string">'.jpg'</span><span>; </span></span></li><li><span>} </span></li></ol>
로그인 후 복사

抓取了自己的个人信息后,就需要再访问用户的关注者和关注了的用户列表获取更多的用户信息。然后一层一层地访问。可以看到,在个人中心页面里,有两个链接如下:

这里有两个链接,一个是关注了,另一个是关注者,以“关注了”的链接为例。用正则匹配去匹配到相应的链接,得到url之后用curl带上cookie再发一次请求。抓取到用户关注了的用于列表页之后,可以得到下面的页面:

分析页面的html结构,因为只要得到用户的信息,所以只需要框住的这一块的div内容,用户名都在这里面。可以看到,用户关注了的页面的url是:

不同的用户的这个url几乎是一样的,不同的地方就在于用户名那里。用正则匹配拿到用户名列表,一个一个地拼url,然后再逐个发请求当然,一个一个是比较慢的,下面有解决方案,这个稍后会说到)。进入到新用户的页面之后,再重复上面的步骤,就这样不断循环,直到达到你所要的数据量。

Linux统计文件数量

脚本跑了一段时间后,需要看看究竟获取了多少图片,当数据量比较大的时候,打开文件夹查看图片数量就有点慢。脚本是在Linux环境下运行的,因此可以使用Linux的命令来统计文件数量:

ls -l | grep "^-" | wc -l

其中, ls -l 是长列表输出该目录下的文件信息这里的文件可以是目录、链接、设备文件等); grep "^-" 过滤长列表输出信息, "^-" 只保留一般文件,如果只保留目录是 "^d"wc -l 是统计输出信息的行数。下面是一个运行示例:

插入MySQL时重复数据的处理

程序运行了一段时间后,发现有很多用户的数据是重复的,因此需要在插入重复用户数据的时候做处理。处理方案如下:

1)插入数据库之前检查数据是否已经存在数据库;

2)添加唯一索引,插入时使用 INSERT INTO ... ON DUPLICATE KEY UPDATE...

3)添加唯一索引,插入时使用 INSERT INGNORE INTO...

4)添加唯一索引,插入时使用 REPLACE INTO...

使用curl_multi实现多线程抓取页面

刚开始单进程而且单个curl去抓取数据,速度很慢,挂机爬了一个晚上只能抓到2W的数据,于是便想到能不能在进入新的用户页面发curl请求的时候一次性请求多个用户,后来发现了curl_multi这个好东西。curl_multi这类函数可以实现同时请求多个url,而不是一个个请求,这类似于linux系统中一个进程开多条线程执行的功能。下面是使用curl_multi实现多线程爬虫的示例:

<ol class="dp-j"><li class="alt"><span><span>$mh = curl_multi_init(); </span><span class="comment">//返回一个新cURL批处理句柄</span><span> </span></span></li><li><span>        <span class="keyword">for</span><span> ($i = </span><span class="number">0</span><span>; $i < $max_size; $i++) </span></span></li><li class="alt"><span>        { </span></li><li><span>            $ch = curl_init();  <span class="comment">//初始化单个cURL会话</span><span> </span></span></li><li class="alt"><span>            curl_setopt($ch, CURLOPT_HEADER, <span class="number">0</span><span>); </span></span></li><li><span>            curl_setopt($ch, CURLOPT_URL, <span class="string">'http://www.zhihu.com/people/'</span><span> . $user_list[$i] . </span><span class="string">'/about'</span><span>); </span></span></li><li class="alt"><span>            curl_setopt($ch, CURLOPT_COOKIE, self::$user_cookie); </span></li><li><span>            curl_setopt($ch, CURLOPT_USERAGENT, <span class="string">'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36'</span><span>); </span></span></li><li class="alt"><span>            curl_setopt($ch, CURLOPT_RETURNTRANSFER, <span class="keyword">true</span><span>);  </span></span></li><li><span>            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, <span class="number">1</span><span>); </span></span></li><li class="alt"><span>            $requestMap[$i] = $ch; </span></li><li><span>            curl_multi_add_handle($mh, $ch);  <span class="comment">//向curl批处理会话中添加单独的curl句柄</span><span> </span></span></li><li class="alt"><span>        } </span></li><li><span> </span></li><li class="alt"><span>        $user_arr = array(); </span></li><li><span>        <span class="keyword">do</span><span> { </span></span></li><li class="alt"><span>                        <span class="comment">//运行当前 cURL 句柄的子连接</span><span> </span></span></li><li><span>            <span class="keyword">while</span><span> (($cme = curl_multi_exec($mh, $active)) == CURLM_CALL_MULTI_PERFORM); </span></span></li><li class="alt"><span>             </span></li><li><span>            <span class="keyword">if</span><span> ($cme != CURLM_OK) {</span><span class="keyword">break</span><span>;} </span></span></li><li class="alt"><span>                        <span class="comment">//获取当前解析的cURL的相关传输信息</span><span> </span></span></li><li><span>            <span class="keyword">while</span><span> ($done = curl_multi_info_read($mh)) </span></span></li><li class="alt"><span>            { </span></li><li><span>                $info = curl_getinfo($done[<span class="string">'handle'</span><span>]); </span></span></li><li class="alt"><span>                $tmp_result = curl_multi_getcontent($done[<span class="string">'handle'</span><span>]); </span></span></li><li><span>                $error = curl_error($done[<span class="string">'handle'</span><span>]); </span></span></li><li class="alt"><span> </span></li><li><span>                $user_arr[] = array_values(getUserInfo($tmp_result)); </span></li><li class="alt"><span> </span></li><li><span>                <span class="comment">//保证同时有$max_size个请求在处理</span><span> </span></span></li><li class="alt"><span>                <span class="keyword">if</span><span> ($i < sizeof($user_list) && isset($user_list[$i]) && $i < count($user_list)) </span></span></li><li><span>                { </span></li><li class="alt"><span>                    $ch = curl_init(); </span></li><li><span>                    curl_setopt($ch, CURLOPT_HEADER, <span class="number">0</span><span>); </span></span></li><li class="alt"><span>                    curl_setopt($ch, CURLOPT_URL, <span class="string">'http://www.zhihu.com/people/'</span><span> . $user_list[$i] . </span><span class="string">'/about'</span><span>); </span></span></li><li><span>                    curl_setopt($ch, CURLOPT_COOKIE, self::$user_cookie); </span></li><li class="alt"><span>                    curl_setopt($ch, CURLOPT_USERAGENT, <span class="string">'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36'</span><span>); </span></span></li><li><span>                    curl_setopt($ch, CURLOPT_RETURNTRANSFER, <span class="keyword">true</span><span>);  </span></span></li><li class="alt"><span>                    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, <span class="number">1</span><span>); </span></span></li><li><span>                    $requestMap[$i] = $ch; </span></li><li class="alt"><span>                    curl_multi_add_handle($mh, $ch); </span></li><li><span> </span></li><li class="alt"><span>                    $i++; </span></li><li><span>                } </span></li><li class="alt"><span> </span></li><li><span>                curl_multi_remove_handle($mh, $done[<span class="string">'handle'</span><span>]); </span></span></li><li class="alt"><span>            } </span></li><li><span> </span></li><li class="alt"><span>            <span class="keyword">if</span><span> ($active) </span></span></li><li><span>                curl_multi_select($mh, <span class="number">10</span><span>); </span></span></li><li class="alt"><span>        } <span class="keyword">while</span><span> ($active); </span></span></li><li><span> </span></li><li class="alt"><span>        curl_multi_close($mh); </span></li><li><span>        <span class="keyword">return</span><span> $user_arr; </span></span></li></ol>
로그인 후 복사

HTTP 429 Too Many Requests

使用curl_multi函数可以同时发多个请求,但是在执行过程中使同时发200个请求的时候,发现很多请求无法返回了,即发现了丢包的情况。进一步分析,使用 curl_getinfo 函数打印每个请求句柄信息,该函数返回一个包含HTTP response信息的关联数组,其中有一个字段是http_code,表示请求返回的HTTP状态码。看到有很多个请求的http_code都是429,这个返回码的意思是发送太多请求了。我猜是知乎做了防爬虫的防护,于是我就拿其他的网站来做测试,发现一次性发200个请求时没问题的,证明了我的猜测,知乎在这方面做了防护,即一次性的请求数量是有限制的。于是我不断地减少请求数量,发现在5的时候就没有丢包情况了。说明在这个程序里一次性最多只能发5个请求,虽然不多,但这也是一次小提升了。

使用Redis保存已经访问过的用户

抓取用户的过程中,发现有些用户是已经访问过的,而且他的关注者和关注了的用户都已经获取过了,虽然在数据库的层面做了重复数据的处理,但是程序还是会使用curl发请求,这样重复的发送请求就有很多重复的网络开销。还有一个就是待抓取的用户需要暂时保存在一个地方以便下一次执行,刚开始是放到数组里面,后来发现要在程序里添加多进程,在多进程编程里,子进程会共享程序代码、函数库,但是进程使用的变量与其他进程所使用的截然不同。不同进程之间的变量是分离的,不能被其他进程读取,所以是不能使用数组的。因此就想到了使用Redis缓存来保存已经处理好的用户以及待抓取的用户。这样每次执行完的时候都把用户push到一个already_request_queue队列中,把待抓取的用户即每个用户的关注者和关注了的用户列表)push到request_queue里面,然后每次执行前都从request_queue里pop一个用户,然后判断是否在already_request_queue里面,如果在,则进行下一个,否则就继续执行。

在PHP中使用redis示例:

<ol class="dp-c"><li class="alt"><span><span><?php </span></span></li><li><span>    <span class="vars">$redis</span><span> = </span><span class="keyword">new</span><span> Redis(); </span></span></li><li class="alt"><span>    <span class="vars">$redis</span><span>->connect(</span><span class="string">'127.0.0.1'</span><span>, </span><span class="string">'6379'</span><span>); </span></span></li><li><span>    <span class="vars">$redis</span><span>->set(</span><span class="string">'tmp'</span><span>, </span><span class="string">'value'</span><span>); </span></span></li><li class="alt"><span>    <span class="keyword">if</span><span> (</span><span class="vars">$redis</span><span>->exists(</span><span class="string">'tmp'</span><span>)) </span></span></li><li><span>    { </span></li><li class="alt"><span>        <span class="func">echo</span><span> </span><span class="vars">$redis</span><span>->get(</span><span class="string">'tmp'</span><span>) . </span><span class="string">"\n"</span><span>; </span></span></li><li><span>    } </span></li></ol>
로그인 후 복사

使用PHP的pcntl扩展实现多进程

改用了curl_multi函数实现多线程抓取用户信息之后,程序运行了一个晚上,最终得到的数据有10W。还不能达到自己的理想目标,于是便继续优化,后来发现php里面有一个pcntl扩展可以实现多进程编程。下面是多编程编程的示例:

<ol class="dp-j"><li class="alt"><span><span class="comment">//PHP多进程demo</span><span> </span></span></li><li><span>    <span class="comment">//fork10个进程</span><span> </span></span></li><li class="alt"><span>    <span class="keyword">for</span><span> ($i = </span><span class="number">0</span><span>; $i < </span><span class="number">10</span><span>; $i++) { </span></span></li><li><span>        $pid = pcntl_fork(); </span></li><li class="alt"><span>        <span class="keyword">if</span><span> ($pid == -</span><span class="number">1</span><span>) { </span></span></li><li><span>            echo <span class="string">"Could not fork!\n"</span><span>; </span></span></li><li class="alt"><span>            exit(<span class="number">1</span><span>); </span></span></li><li><span>        } </span></li><li class="alt"><span>        <span class="keyword">if</span><span> (!$pid) { </span></span></li><li><span>            echo <span class="string">"child process $i running\n"</span><span>; </span></span></li><li class="alt"><span>            <span class="comment">//子进程执行完毕之后就退出,以免继续fork出新的子进程</span><span> </span></span></li><li><span>            exit($i); </span></li><li class="alt"><span>        } </span></li><li><span>    } </span></li><li class="alt"><span>     </span></li><li><span>    <span class="comment">//等待子进程执行完毕,避免出现僵尸进程</span><span> </span></span></li><li class="alt"><span>    <span class="keyword">while</span><span> (pcntl_waitpid(</span><span class="number">0</span><span>, $status) != -</span><span class="number">1</span><span>) { </span></span></li><li><span>        $status = pcntl_wexitstatus($status); </span></li><li class="alt"><span>        echo <span class="string">"Child $status completed\n"</span><span>; </span></span></li><li><span>    } </span></li></ol>
로그인 후 복사

在Linux下查看系统的cpu信息

实现了多进程编程之后,就想着多开几条进程不断地抓取用户的数据,后来开了8调进程跑了一个晚上后发现只能拿到20W的数据,没有多大的提升。于是查阅资料发现,根据系统优化的CPU性能调优,程序的最大进程数不能随便给的,要根据CPU的核数和来给,最大进程数最好是cpu核数的2倍。因此需要查看cpu的信息来看看cpu的核数。在Linux下查看cpu的信息的命令:

cat /proc/cpuinfo

其中,model name表示cpu类型信息,cpu cores表示cpu核数。这里的核数是1,因为是在虚拟机下运行,分配到的cpu核数比较少,因此只能开2条进程。最终的结果是,用了一个周末就抓取了110万的用户数据。

多进程编程中Redis和MySQL连接问题

在多进程条件下,程序运行了一段时间后,发现数据不能插入到数据库,会报mysql too many connections的错误,redis也是如此。

下面这段代码会执行失败:

<ol class="dp-j"><li class="alt"><span><span><?php </span></span></li><li><span>     <span class="keyword">for</span><span> ($i = </span><span class="number">0</span><span>; $i < </span><span class="number">10</span><span>; $i++) { </span></span></li><li class="alt"><span>          $pid = pcntl_fork(); </span></li><li><span>          <span class="keyword">if</span><span> ($pid == -</span><span class="number">1</span><span>) { </span></span></li><li class="alt"><span>               echo <span class="string">"Could not fork!\n"</span><span>; </span></span></li><li><span>               exit(<span class="number">1</span><span>); </span></span></li><li class="alt"><span>          } </span></li><li><span>          <span class="keyword">if</span><span> (!$pid) { </span></span></li><li class="alt"><span>               $redis = PRedis::getInstance(); </span></li><li><span>               <span class="comment">// do something     </span><span> </span></span></li><li class="alt"><span>               exit; </span></li><li><span>          } </span></li><li class="alt"><span>     } </span></li></ol>
로그인 후 복사

根本原因是在各个子进程创建时,就已经继承了父进程一份完全一样的拷贝。对象可以拷贝,但是已创建的连接不能被拷贝成多个,由此产生的结果,就是各个进程都使用同一个redis连接,各干各的事,最终产生莫名其妙的冲突。

解决方法:

程序不能完全保证在fork进程之前,父进程不会创建redis连接实例。因此,要解决这个问题只能靠子进程本身了。试想一下,如果在子进程中获取的实例只与当前进程相关,那么这个问题就不存在了。于是解决方案就是稍微改造一下redis类实例化的静态方式,与当前进程ID绑定起来。

改造后的代码如下:

<ol class="dp-j"><li class="alt"><span><span><?php </span></span></li><li><span>     <span class="keyword">public</span><span> </span><span class="keyword">static</span><span> function getInstance() { </span></span></li><li class="alt"><span>          <span class="keyword">static</span><span> $instances = array(); </span></span></li><li><span>          $key = getmypid();<span class="comment">//获取当前进程ID</span><span> </span></span></li><li class="alt"><span>          <span class="keyword">if</span><span> ($empty($instances[$key])) { </span></span></li><li><span>               $inctances[$key] = <span class="keyword">new</span><span> self(); </span></span></li><li class="alt"><span>          } </span></li><li><span>      </span></li><li class="alt"><span>          <span class="keyword">return</span><span> $instances[$key]; </span></span></li><li><span>     } </span></li></ol>
로그인 후 복사

PHP统计脚本执行时间

因为想知道每个进程花费的时间是多少,因此写个函数统计脚本执行时间:

<ol class="dp-j"><li class="alt"><span><span>function microtime_float() </span></span></li><li><span>{ </span></li><li class="alt"><span>     list($u_sec, $sec) = explode(<span class="string">' '</span><span>, microtime()); </span></span></li><li><span>     <span class="keyword">return</span><span> (floatval($u_sec) + floatval($sec)); </span></span></li><li class="alt"><span>} </span></li><li><span> </span></li><li class="alt"><span>$start_time = microtime_float(); </span></li><li><span> </span></li><li class="alt"><span><span class="comment">//do something</span><span> </span></span></li><li><span>usleep(<span class="number">100</span><span>); </span></span></li><li class="alt"><span> </span></li><li><span>$end_time = microtime_float(); </span></li><li class="alt"><span>$total_time = $end_time - $start_time; </span></li><li><span> </span></li><li class="alt"><span>$time_cost = sprintf(<span class="string">"%.10f"</span><span>, $total_time); </span></span></li><li><span> </span></li><li class="alt"><span>echo <span class="string">"program cost total "</span><span> . $time_cost . </span><span class="string">"s\n"</span><span>; </span></span></li></ol>
로그인 후 복사

数据分析

抓取了110万的数据后,小小做了一些数据分析,结果如下:

若文中有不正确的地方,望各位指出以便改正。



www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1059211.htmlTechArticlePHP开发:使用PHP抓取百万知乎用户以及知识点札记 代码托管地址:https://github.com/hhqcontinue/zhihuSpider 开发前的准备 安装Linux系统Ubuntu14.04),...
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Scrapy 사례 분석: LinkedIn에서 회사 정보를 크롤링하는 방법 Scrapy 사례 분석: LinkedIn에서 회사 정보를 크롤링하는 방법 Jun 23, 2023 am 10:04 AM

Scrapy는 인터넷에서 관련 정보를 빠르고 쉽게 얻을 수 있는 Python 기반 크롤러 프레임워크입니다. 이 기사에서는 Scrapy 사례를 사용하여 LinkedIn에서 회사 정보를 크롤링하는 방법을 자세히 분석합니다. 대상 URL 결정 먼저 대상이 LinkedIn의 회사 정보임을 분명히 해야 합니다. 따라서 LinkedIn 회사 정보 페이지의 URL을 찾아야 합니다. LinkedIn 웹사이트를 열고 검색창에 회사 이름을 입력한 후

PHP를 사용하여 Instagram 정보를 스크랩하는 예 PHP를 사용하여 Instagram 정보를 스크랩하는 예 Jun 13, 2023 pm 06:26 PM

인스타그램은 수억 명의 활성 사용자를 보유한 오늘날 가장 인기 있는 소셜 미디어 중 하나입니다. 사용자는 수십억 개의 사진과 비디오를 업로드하며 이 데이터는 많은 기업과 개인에게 매우 중요합니다. 따라서 인스타그램 데이터를 자동으로 스크랩하는 프로그램을 사용해야 하는 경우가 많습니다. 이 기사에서는 PHP를 사용하여 Instagram 데이터를 캡처하는 방법을 소개하고 구현 예제를 제공합니다. PHP용 cURL 확장 설치 cURL은 다양한 용도로 사용되는 도구입니다.

PHP를 사용하여 Zhihu 질문과 답변을 캡처하는 프로그램 구현 PHP를 사용하여 Zhihu 질문과 답변을 캡처하는 프로그램 구현 Jun 13, 2023 pm 11:21 PM

매우 인기 있는 지식 공유 커뮤니티인 Zhihu에는 많은 고품질 질문과 답변을 제공하는 많은 사용자가 있습니다. 공부하고 일하는 사람들에게 이 콘텐츠는 문제를 해결하고 시야를 넓히는 데 매우 도움이 됩니다. 이 콘텐츠를 정리하고 활용하려면 스크레이퍼를 사용하여 관련 데이터를 얻어야 합니다. 이 기사에서는 PHP를 사용하여 Zhihu 질문과 답변을 크롤링하는 프로그램을 작성하는 방법을 소개합니다. 소개 Zhihu는 질문, 답변, 칼럼, 주제, 사용자 등을 포함하되 이에 국한되지 않는 매우 풍부한 콘텐츠를 갖춘 플랫폼입니다. 우리는 통과할 수 있다

Scrapy를 사용하여 웹사이트 데이터를 구문 분석하고 스크랩하는 방법 Scrapy를 사용하여 웹사이트 데이터를 구문 분석하고 스크랩하는 방법 Jun 23, 2023 pm 12:33 PM

Scrapy는 웹사이트 데이터를 스크랩하고 구문 분석하기 위한 Python 프레임워크입니다. 개발자가 쉽게 웹 사이트 데이터를 크롤링하고 분석하여 데이터 마이닝 및 정보 수집과 같은 작업을 수행할 수 있도록 도와줍니다. 이 기사에서는 Scrapy를 사용하여 간단한 크롤러 프로그램을 만들고 실행하는 방법을 공유합니다. 1단계: Scrapy 설치 및 구성 Scrapy를 사용하기 전에 먼저 Scrapy 환경을 설치하고 구성해야 합니다. Scrapy는 다음을 실행하여 설치할 수 있습니다: pipinstallscra

URL 전달 및 크롤링을 구현하기 위한 Nginx 리디렉션 구성 구문 분석 URL 전달 및 크롤링을 구현하기 위한 Nginx 리디렉션 구성 구문 분석 Jul 04, 2023 pm 06:37 PM

URL 전달 및 크롤링을 구현하기 위한 Nginx 리디렉션 구성 구문 분석 소개: 웹 애플리케이션 개발에서 URL을 리디렉션해야 하는 상황에 자주 직면합니다. Nginx는 고성능 웹 서버이자 역방향 프록시 서버로서 강력한 리디렉션 기능을 제공합니다. 이 기사에서는 Nginx의 리디렉션 구성을 분석하고 코드 예제를 통해 URL 전달 및 크롤링 기능을 구현하는 방법을 보여줍니다. 1. 기본 개념 리디렉션은 URL 요청을 다른 URL로 전달하는 프로세스를 의미합니다. Nginx에서

Java 크롤러 사용: 웹페이지 데이터를 효율적으로 추출하기 위한 실용적인 방법 및 기술 Java 크롤러 사용: 웹페이지 데이터를 효율적으로 추출하기 위한 실용적인 방법 및 기술 Jan 05, 2024 am 08:15 AM

Java 크롤러 실습: 웹 페이지 데이터를 빠르게 크롤링하는 방법 및 기술 서론: 인터넷의 발달로 인해 웹 페이지에는 막대한 정보가 저장되며, 사람들이 웹 페이지에서 유용한 데이터를 얻는 것이 점점 더 어려워지고 있습니다. 크롤러 기술을 사용하면 웹페이지 데이터를 자동으로 신속하게 크롤링하고 필요한 유용한 정보를 추출할 수 있습니다. 이 기사에서는 Java를 사용한 크롤러 개발 방법과 기술을 소개하고 구체적인 코드 예제를 제공합니다. 1. 적절한 크롤러 프레임워크를 선택하십시오. Java 필드에는 Jso와 같이 선택할 수 있는 우수한 크롤러 프레임워크가 많이 있습니다.

PHP와 phpSpider를 사용하여 특정 웹사이트 콘텐츠를 정확하게 크롤링하는 방법은 무엇입니까? PHP와 phpSpider를 사용하여 특정 웹사이트 콘텐츠를 정확하게 크롤링하는 방법은 무엇입니까? Jul 22, 2023 pm 08:29 PM

PHP와 phpSpider를 사용하여 특정 웹사이트 콘텐츠를 정확하게 크롤링하는 방법은 무엇입니까? 서론: 인터넷의 발달로 인해 웹사이트에 존재하는 데이터의 양이 증가하고 있으며, 수작업을 통해 필요한 정보를 얻는 것은 비효율적입니다. 따라서 특정 웹사이트의 콘텐츠를 얻기 위해 자동화된 크롤링 도구를 사용해야 하는 경우가 많습니다. PHP 언어와 phpSpider 라이브러리는 매우 실용적인 도구 중 하나입니다. 이 기사에서는 PHP 및 phpSpider를 사용하여 특정 웹사이트 콘텐츠를 정확하게 크롤링하는 방법을 소개하고 코드 예제를 제공합니다. 1. 설치

URL 전달 및 크롤링을 구현하기 위한 Nginx 리디렉션 구성 튜토리얼 URL 전달 및 크롤링을 구현하기 위한 Nginx 리디렉션 구성 튜토리얼 Jul 05, 2023 am 11:42 AM

URL 전달 및 크롤링을 구현하기 위한 Nginx 리디렉션 구성 튜토리얼 Nginx는 역방향 프록시, 로드 밸런싱, URL 리디렉션과 같은 기능을 구현하는 데에도 사용할 수 있는 고성능 오픈 소스 웹 서버입니다. 이 글에서는 Nginx 구성을 통해 URL 리디렉션 및 크롤링을 구현하는 방법을 소개하고 관련 코드 예제를 제공합니다. 1. URL 전달 URL 전달이란 URL 요청을 다른 URL 주소로 전달하는 것을 말합니다. Nginx에서는 구성을 통해 URL을 구현할 수 있습니다.

See all articles