说明:文中部份内容来自书籍和网络,部份内容为本身的理解。但愿借助笔记的方式可以加深本身对该部分知识的掌握,也做为往后回顾的记录。
最开始使用 PHP 因此先说说 PHP 的优势:
1.语言比较简单,PHP 是很是随意的一种语言。写起来容易让你把精力放在你要作的事情上,而不是各类语法规则等等。
2.各类功能模块齐全,这里分两部分:
1.网页下载:curl 等扩展库;
2.文档解析:dom、xpath、tidy、各类转码工具,可能跟题主的问题不太同样,个人爬虫须要提取正文,因此须要很复杂的文本处理,因此各类方便的文本处理工具是个人大爱。;
总之容易上手。php
缺点:
1.并发处理能力较弱:因为当时 PHP 没有线程、进程功能,要想实现并发须要借用多路服用模型,PHP 使用的是 select 模型。实现其来比较麻烦,多是由于水平问题个人程序常常出现一些错误,致使漏抓。html
/** * 爬虫 * @return array */ public function paChong(Request $request){ $params = array(); $complexname = $request->complexname; if($complexname){ $params['complexname'] = $complexname; }else{ $params['$pg'] = $request->pg; $params['$pgsz'] = $request->pgsz; } $url = 'http://xxxxxxxxx'; $res = curl($url, $params); $reg = '/<tr.*?>(.*?)<\/tr>/ism'; $result = preg_match_all($reg,$res,$match_result); array_shift($match_result[0]);//使用 array_shift 删除数组的第一个元素 array_pop($match_result[0]);//使用 array_pop 删除数组的最后一个元素 $company = array(); foreach ($match_result[0] as $key => $value) { $pattern_num = '/<td data-header="xxx" (.*?)>(.*?)<div/ism'; preg_match_all($pattern_num, $value, $matches_num); $matches_num[2][0] = str_replace(array("\t", "\r\n", " "), '', $matches_num[2][0]); $company['company_num'][] = $matches_num[2][0]; $pattern = '/<td data-header="xxxx" >(.*?)<\/td>/ism'; preg_match_all($pattern, $value, $matches); $matches[1][0] = str_replace(array("\t", "\r\n"), '', $matches[1][0]); $pattern_str = '/<a target="_blank" href="(.*?)">(.*?)<\/a>/ism'; preg_match_all($pattern_str, $matches[1][0], $matche); $company['company_name'][] = $matche[2][0]; $company['company_url'][] = 'http://xxxxx' . $matche[1][0]; $pattern_reason = '/<td data-header="xxx" (.*?)<\/td>/ism'; preg_match_all($pattern_reason, $value, $matches_reason); $pattern_reason2 = '/<\/div>(.*?)<\/td>/ism'; preg_match_all($pattern_reason2, $value, $matches_reason2); $matches_reason2[1][1] = str_replace(array("\t", "\r\n", " "), '', $matches_reason2[1][1]); $company['company_sesion'][] = $matches_reason2[1][1]; $pattern_branch = '/<td data-header="xxxx">(.*?)<\/td>/ism'; preg_match_all($pattern_branch, $value, $matches_branch); $company['company_branch'][] = $matches_branch[1][0]; $pattern_start = '/<td data-header="xxxxx">(.*?)<\/td>(.*?)<td data-header="xxxx">(.*?)<\/td>/ism'; preg_match_all($pattern_start, $value, $matches_start); $company['company_start'][] = $matches_start[1][0]; $company['company_end'][] = $matches_start[3][0]; } dd($company); }
再说说 Python:
优势:
1.各类爬虫框架,方便高效的下载网页;
2.多线程、进程模型成熟稳定,爬虫是一个典型的多任务处理场景,请求页面时会有较长的延迟,整体来讲更多的是等待。多线程或进程会更优化程序效率,提高整个系统下载和分析能力。
3.GAE 的支持,当初写爬虫的时候刚刚有 GAE,并且只支持 Python ,利用 GAE 建立的爬虫几乎免费,最多的时候我有近千个应用实例在工做。python
缺点:
1.对不规范 HTML 适应能力差:举个例子,若是一个页面里面同时有 GB18030 字符集的中文和 UTF-8 字符集的中文,Python 处理起来就没有 PHP 那么简单,你本身须要作不少的判断工做。固然这是提取正文时的麻烦。git
# code utf-8 import urllib.request import urllib.parse import re import MySQLdb db = MySQLdb.connect(host="127.0.0.1",user ="root",passwd="root",port =3306,db ="py_test",charset='utf8') cursor = db.cursor() sql = "INSERT INTO py_test (id, item, result,department,indata,outdata) VALUES (%s, %s,%s,%s,%s,%s)" data = { "pg": "3", "pgsz": "3" } base_url = 'http://xxxxxxx' headers={"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 QIHU 360SE"} postdata=urllib.parse.urlencode(data).encode('utf-8') req=urllib.request.Request(url=base_url,headers=headers,data=postdata,method='POST') response=urllib.request.urlopen(req).read() html=response.decode() results1 = re.findall('<td data-header="xxxxx" class="github-posi">.*?(\d+).*?<div',html,re.DOTALL) results2 = re.findall('<td data-header="xxxx" >.*?<a target="_blank" href=".*?">(.*?)\r\n\t\t\t\t\t\t<',html,re.DOTALL) results3 = re.findall('<td data-header="xxxx" style="text-align: left;">\r\n\t\t\t\t\t\t<div style="margin-bottom:4px">\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t(.*?)\r\n\t\t\t\t\t</td>',html,re.DOTALL) results4 = re.findall('<td data-header="xxxx">(.*?)</td>',html,re.DOTALL) results5 = re.findall(' <td data-header="xxxx">(.*?)</td>.*?<td data-header="xxxx">(.*?)</td>',html,re.DOTALL) for i, text in enumerate(results1): val = results1[i].encode('utf-8'),results2[i].encode('utf-8'),results3[i].encode('utf-8'),results4[i].encode('utf-8'),results5[i][0].encode('utf-8'),results5[i][1].encode('utf-8') print(val) cursor.execute(sql, val) db.commit() db.close()
最后说一下个人感觉。由于我是phper,因此用php能够很简单的上手,无非就是post提交加上正则提取,总体写下来感受超级简单。可是为了以防万一,怕后期会有多进程,我将python教程大体看了一遍。发现python确实有不少自身带的库很适合写爬虫,并且到后期能够多进程,因此尽可能仍是用python,目前正在学习中…github