Experience
一个研究生同学因为学习需要,想提取一个网站的数据,然后把这些数据都放入excel当中。
刚开始我很不在意,以前什么样的爬虫没见过,这次不过是要把数据放入excel中而已。
于是我在网上找到一个结合php生成excel的工具——PHPExcel
然后写了一个简单的程序,结果!!!失败了= =
遇到的问题
1.需要读取的数据太多,一共1400多个网页需要读取(也许我太笨,没找到一次读取数据的接口)。
2.那个网站的服务器太差,打开一个网页需要很长时间,而且经常出现请求超时的情况。
3.上面找的那个生成excel的工具不适合读取这么多的数据。
解决办法
1.关于生成excel。我看了一下phpmyadmin,找到了一个将数据库导出为excel的功能,而且导出的速度很快,于是我打算先把数据写入mysql中。
2.针对请求超时。刚开始每次超时我都重新运行一下程序,这样做实在太浪费时间了。于是我在程序中,每次超时都重新读取一次网页,最多读3次,否则在数据库中写入空的数据,然后读下一个网页。结果发现,这样做的成功率几乎是100%。
<?php
//避免程序运行30秒后停止
ini_set('max_execution_time', '0');
header("content-Type: text/html; charset=utf8");
//连接数据库
$conn=mysql_connect("localhost","root","")or die("连接错误");
mysql_select_db("newdb",$conn);
mysql_query("set names 'utf8'");
//读取网页超时时间
$opts = array(
'http'=>array(
'method'=>"GET",
'timeout'=>15,//单位秒
)
);
for($i = 1; $i<143; $i++)
{
//读取超时后重新读网页内容,最多3次,否则数据出错
$cnt1=0;
while($cnt1<3 && ($strJson=file_get_contents("http://stockdata.stock.hexun.com/zrbg/data/zrbList.aspx?date=2014-12-31&count=20&page=".$i, false, stream_context_create($opts)))===FALSE)
$cnt1++;
$strJson = iconv("gb2312", "utf-8//IGNORE",$strJson);
preg_match_all('/(?<=industry:\').+?(?=\',stockNumber)/', $strJson, $arrLala); //获得所有企业名称
preg_match_all('/(?<=StockNameLink:\').+?(?=\',industry)/', $strJson, $arrLala2); //获得所有链接
for($j = 0; $j <20; $j++)
{
$cnt=0;
while($cnt<3 && ($str=file_get_contents("http://stockdata.stock.hexun.com/zrbg/".$arrLala2[0][$j], false, stream_context_create($opts)))===FALSE)
$cnt++;
$str = iconv("gb2312", "utf-8//IGNORE",$str);
preg_match_all('/(?<=\().+?分/', $str, $arr);
preg_match_all('/(?<=:).+?(?=<)/', $str, $arr2);
$sql="insert into report(
a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,u1,v1,w1,x1,y1,z1,
a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,
a3,b3,c3,d3) values('".$arrLala[0][$j]."','".$arr[0][0]."','".$arr[0][1]."','".$arr2[0][5]."','".$arr2[0][6]."','".$arr2[0][7]."','".$arr2[0][8]."','".$arr2[0][9]."','".$arr2[0][10]."','".
$arr[0][8]."','".$arr2[0][11]."','".$arr2[0][12]."','".$arr2[0][13]."','".$arr2[0][14]."','".$arr2[0][15]."','".
$arr[0][14]."','".$arr2[0][16]."','".$arr2[0][17]."','".$arr2[0][18]."','".
$arr[0][18]."','".$arr2[0][19]."','".
$arr[0][20]."','".$arr2[0][20]."','".$arr2[0][21]."','".$arr2[0][22]."','".
$arr[0][24]."','".$arr[0][25]."','".$arr2[0][23]."','".$arr2[0][24]."','".
$arr[0][28]."','".$arr2[0][25]."','".$arr2[0][26]."','".
$arr[0][31]."','".$arr2[0][27]."','".$arr2[0][28]."','".$arr2[0][29]."','".
$arr[0][35]."','".$arr[0][36]."','".$arr2[0][30]."','".$arr2[0][31]."','".
$arr[0][39]."','".$arr2[0][32]."','".
$arr[0][41]."','".$arr2[0][33]."','".$arr2[0][34]."','".
$arr[0][44]."','".$arr[0][45]."','".$arr2[0][35]."','".$arr2[0][36]."','".$arr2[0][37]."','".$arr2[0][38]."','".$arr2[0][39]."','".
$arr[0][51]."','".$arr[0][52]."','".$arr2[0][40]."','".$arr2[0][41]."')";
mysql_query($sql,$conn);
}
}
echo "success!";
?>
如果有读取失败,或者读取错误的数据,只要用下面的程序读取更新数据即可。
<?php
//避免程序运行30秒后停止
ini_set('max_execution_time', '0');
header("content-Type: text/html; charset=utf8");
//连接数据库
$conn=mysql_connect("localhost","root","")or die("连接错误");
mysql_select_db("newdb",$conn);
mysql_query("set names 'utf8'");
//读取网页超时时间
$opts = array(
'http'=>array(
'method'=>"GET",
'timeout'=>2,//单位秒
)
);
$cnt=0;
while($cnt<3 && ($str=file_get_contents("http://stockdata.stock.hexun.com/zrbg/stock_bg.aspx?code=300256", false, stream_context_create($opts)))===FALSE)
{
$cnt++;
if($cnt<3)
echo "Try to get contents again...<br>";
else
echo "Read failed!<br>";
}
$str = iconv("gb2312", "utf-8//IGNORE",$str);
preg_match_all('/(?<=\().+?分/', $str, $arr);
preg_match_all('/(?<=:).+?(?=<)/', $str, $arr2);
$sql = "update report set b1='".$arr[0][0]."',
c1='".$arr[0][1]."',
d1='".$arr2[0][5]."',
e1='".$arr2[0][6]."',
f1='".$arr2[0][7]."',
g1='".$arr2[0][8]."',
h1='".$arr2[0][9]."',
i1='".$arr2[0][10]."',
j1='".$arr[0][8]."',
k1='".$arr2[0][11]."',
l1='".$arr2[0][12]."',
m1='".$arr2[0][13]."',
n1='".$arr2[0][14]."',
o1='".$arr2[0][15]."',
p1='".$arr[0][14]."',
q1='".$arr2[0][16]."',
r1='".$arr2[0][17]."',
s1='".$arr2[0][18]."',
t1='".$arr[0][18]."',
u1='".$arr2[0][19]."',
v1='".$arr[0][20]."',
w1='".$arr2[0][20]."',
x1='".$arr2[0][21]."',
y1='".$arr2[0][22]."',
z1='".$arr[0][24]."',
a2='".$arr[0][25]."',
b2='".$arr2[0][23]."',
c2='".$arr2[0][24]."',
d2='".$arr[0][28]."',
e2='".$arr2[0][25]."',
f2='".$arr2[0][26]."',
g2='".$arr[0][31]."',
h2='".$arr2[0][27]."',
i2='".$arr2[0][28]."',
j2='".$arr2[0][29]."',
k2='".$arr[0][35]."',
l2='".$arr[0][36]."',
m2='".$arr2[0][30]."',
n2='".$arr2[0][31]."',
o2='".$arr[0][39]."',
p2='".$arr2[0][32]."',
q2='".$arr[0][41]."',
r2='".$arr2[0][33]."',
s2='".$arr2[0][34]."',
t2='".$arr[0][44]."',
u2='".$arr[0][45]."',
v2='".$arr2[0][35]."',
w2='".$arr2[0][36]."',
x2='".$arr2[0][37]."',
y2='".$arr2[0][38]."',
z2='".$arr2[0][39]."',
a3='".$arr[0][51]."',
b3='".$arr[0][51]."',
c3='".$arr2[0][40]."',
d3='".$arr[0][41]."'
where a1='星星科技(300256)'";
mysql_query($sql,$conn);
?>