当前位置: 首页 > 后端技术 > PHP

php爬虫抓取好用的免费API

时间:2023-03-30 04:50:00 PHP

做了一个爬虫api的类。可以获得2017年全国行政区域。git:https://github.com/buffge/loa...效果图:差不多40000行,只需要90秒就爬完了。首先,这个api在阿里云市场是免费的。每个人都可以使用它。地址在这里。必须先注册阿里云,然后购买。一次只能购买1000个。可以买三四次,应该可以全部下载。爬虫思路:1.初始化curl_multi,将curlhandle加入其中。2.执行所有curl句柄3.处理curl返回的所有结果。api有两个接口。第一种是通过名称获取城市信息,第二种是通过父城市id获取所有子城市。因为我们不知道父城市id,所以第一步必须通过名称获取城市的信息。定义一个全国所有省级行政区的数组(共34个)。爬虫运行顺序的第一步就是获取这34个省(level=1)的信息。第二步,每次循环34次,查询当前城市(level=2)的所有子城市。第三步循环(level=2)城市个数,查询Level=3城市信息第四步循环(level=3)城市个数,查询level=4城市信息。最高是level4,也就是有些乡镇级别的城市连level3都没有。它会继续代码块分析publicfunctionstart(){//启动一个mcurl$mh=curl_multi_init();$orinigal_chs=[];//初始化mcurl并添加一定量(最多所有或最大并发)curl到$this->curlMultiInit($mh,$orinigal_chs);//执行所有curl句柄并返回所有curl句柄数组$chs=$this->curlMultiExec($mh,$orinigal_chs);//获取curl返回的所有结果$res=$this->getCurlResult($chs);//如果是正常结果if(is_array($res)){//处理每个curl结果$this->dataHandle($res);}else{//输出错误信息echo"当前列表中没有子城市。\n";}}这是启动方法,所有操作都在里面。这是一个多线程爬虫。如果没有可以百度。核心代码是处理curl结果的最后一个方法;主要内容是将上次获取的城市信息插入到数据库中,然后对获取到的每个城市进行子城市查询,就是上面的。因为是新手,很久没有用过mysql了。不知道为什么这里的affected_rows总是等于-1。如果你知道,你可以告诉我。如下:protectedfunctiondataHandle(array$res){$mysqli=new\mysqli($this->host,$this->name,$this->pwd,$this->dbname);foreach($resas$k=>$v){$mixedInfo=json_decode($v[0]);$cityInfo=$mixedInfo->showapi_res_body->data;$citysLength=count($cityInfo);$sql="INSERTINTO`allcitys`(`provinceId`,`simpleName`,`lon`,`areaCode`,`cityId`,`remark`,`prePinYin`,`cid`,`pinYin`,`parentId`,`level`,`areaName`,`simplePy`,`zipCode`,`countyId`,`lat`,`wholeName`)VALUES";$sql_values='';对于($i=0;$i<$citysLength;$i++){$sql_values.="('{$cityInfo[$i]->provinceId}','{$cityInfo[$i]->simpleName}','{$cityInfo[$i]->lon}','{$cityInfo[$i]->areaCode}','{$cityInfo[$i]->cityId}','{$cityInfo[$i]->remark}','{$cityInfo[$i]->prePinYin}','{$cityInfo[$i]->id}',\"{$cityInfo[$i]->拼音}\",'{$cityInfo[$i]->parentId}','{$cityInfo[$i]->level}','{$cityInfo[$i]->areaName}','{$cityInfo[$i]->simplePy}','{$cityInfo[$i]->zipCode}','{$cityInfo[$i]->countyId}','{$cityInfo[$i]->lat}','{$cityInfo[$i]->wholeName}'),";}$sql_values=substr_replace($sql_values,'',-1);$sql.=$sql_values;$mysqli->query($sql);//不知道为什么这里的affect_rows总是-1//if($mysqli->affected_rows==$citysLength){if(1){echo"{$citysLength}条数据添加成功\n";如果($this->level<4){$temp_level=$this->level+1;对于($j=0;$j<$citysLength;$j++){$tempearchCitysList[]=$cityInfo[$j]->id;}$config=['appcode'=>$this->appcode,'level'=>$temp_level,'amount'=>$citysLength,'getInfo'=>self::SUB_LIST,'searchCitysList'=>$tempearchCitysList,'host'=>$this->host,'name'=>$this->name,'pwd'=>$this->pwd,'dbname'=>$this->dbname];$subLoad=newself($config);$tempearchCitysList=[];$subLoad->start();}}else{echo$this->searchCitysList[$k]。"数据插入失败!\n";}}$mysqli->close();}更难的代码块是curl_multi方法。检查后没有找到满意的答案。然后就随便写了。效果还不错。其中,$mrc=curl_multi_exec($mh,$active);表示执行$mh中的所有curl句柄。$active表示当前处于活动状态,还有多少未完成。$info=curl_multi_info_read($mh,$msgq);这里这句话是读取已经执行过的$mh的内容。如果$info为true,说明curlhandle已经完成,接下来我们从这个info中读入的handle就是当前的curlhandle。如果$info为false,会延迟1000微秒,因为执行速度太快,cpu压力大。因为我英文不好,看不懂官方文档,底层也没学,这里很多东西都是我根据效果猜的。如果其中有任何错误,请告诉我。不仅是这个api,其他的api也可以通过这种思路爬取。图片站小说站可以这样爬。半年前做了一个爬图片网站的课程。它也可以在git上使用。希望对大家有所帮助。