php正则
先说点题外话。自从给电脑安装了Opera 10.0.1750.0 任务栏就开始莫名其妙的时不时就完全卡死,任务管理器也打不开。因为总是在Opera开启一段时间后出现死机的状况,还以为是Opera有内存泄漏。直到今天早上发现开GaussianView也卡死了,才猜想是中了蠕虫一类病毒。虽然,用Chrome仍然不会卡死(那好吧,在Opera给我留下这样的第一印象的情况下,我只好让它失去不久前才给它分配的“默认浏览器”的权利了)。全盘杀毒
出现了一堆病毒。难道是Opera的安装程序带毒?但是用Rising单杀Opera的相关文件夹,没有发现病毒。(我是很喜欢Opera的,最钟爱的就是它的鼠标手势。当然,Chrome及时响应的界面风格(响应鼠标移动,任何动作都会引起界面的变化,而且,鼠标拿开后,效果是渐渐消失的。可以把它定义成“瞬入淡出”效果吧,与“淡入淡出”让人感觉系统变慢完全是两种不同的感觉)是最吸引我的(用惯了Chrome,刚改用Opera,老是把鼠标放在文本上,然后就无限纳闷地看着指针——为什么还没变成工字型?还有就是Opera的上下文菜单项没有相应按键。对于我这种经常在桌面上点击右键紧接着按R的习惯来说,简直就是一大恶梦——右键了居然还要用鼠标选菜单项,这样长久下去,左手不就萎缩了……
杀毒完了,发现有uizvr.sys文件在C:\WINDOWS\System32\下,提示删除失败。而网上又搜索不到。真不知道是什么,各位读者若有知道的,不妨告诉我一下。在下非常感谢!
发现杀了好几个Rootkit病毒,但是网上没有相关的症状说明,所以我还是不确信是不是这个病毒导致了Opera变慢。总之,杀毒完了再打开Opera,内存占用从先前的100~400MB减小到了50~200MB,感觉还行,那就恢复Opera的试用期吧,要是你再敢……
废话少说,看看php的正则表达式吧。
这是获取目标网页上所有链接地址的php代码:
<?php
$url="http://www.163.com";
$html=file_get_contents($url,"r");
preg_match_all ("/(<a)([^>]*)(href=)([^>]*)(>)([^<]*)(<)([^>]*)(>)/", $html, $matches);
for ($i=0;$i<count($matches);$i++)
{
echo "|||".$matches[$i]."||".$matches[$i].$matches[$i]."||".$matches[$i]."||".$matches[$i]."<br>";
}
?>
看看里面的/(<a)([^>]*)(href=)([^>]*)(>)([^<]*)(<)([^>]*)(>)/吧。
我们知道,链接的形式是这样的:
<a href="location">text</a>当然,这是最简单的文本链接。
复杂一点的,比如链接里包含图片的,有style信息的,无非是这样的结构:
<a*****href="location"*****>****</a>
正则表达式就该这样写了:(每个部分用小括号括起来)
1.起始是亘古不变的<a
2.接下来是不包括">"在内的任意字符,当然不会有"<"出现。[^>]代表任意一个不是">"的字符,.代表任意字符,*表示重复前面的字符0~任意有限次。
我们知道,<a后面跟任意个非">"字符后,必定遇到href=来定义它的链接地址。要是用这样的正则:
/(<a) (.*)(>)(href=)/
会出现什么情况呢?
这时,preg_match()会往后搜索,直到行尾前的最后一个">",中间所有的">"都被忽略了。这时,再搜索href=就跑到第二个链接里去了,所以不能用,这一个:
/(<a)([^>]*)(href=) /
[^>]*限制重复的内容不能是">"所以,遇到">"就不会往下搜索下去,从而停留在第一次匹配(href=)的地方。这样看来,
/(<a)(.*)(href=)/也是不可行的,试试看:
<?php
$url="http://www.163.com";
$html=file_get_contents($url,"r");
preg_match_all ("/(<a)(.*)(href=)([^>]*)(>)([^<]*)(<)([^>]*)(>)/", $html, $matches);
for ($i=0;$i<count($matches);$i++)
{
echo "|||".$matches[$i]."||".$matches[$i].$matches[$i]."||".$matches[$i]."||".$matches[$i]."<br>";
}
?>
刷新页面,Chrome审查元素,发现有这样的文本:
||| href="http://reg.163.com/reg0.shtml">注册通行证</a> |<a || 这表明分段失败了:
因为要求输出的第2、3、4、6、8个括号里都没有写明要输出<或>,同时,|||和||中间的内容属于第二个括号(.*)的。
后面的第三个括号:
3.固定的href=
4.把第一个 ">"之前的内容放在这里[^>]*
5.第一个>
6.把接下来第一个"<"之前的内容放在这里[^<]*
7.<
8.">"之前的内容[^>]*
9.>
这样的话,一个基本可用的正则表达式就诞生了。
其实,可以把最后一个括号改成(/a>) 这样的话, 就能保证每次搜索结束时,总是到达链接的结尾处。用原来的(>)在遇到这样的状况时:
<a href="location"><img src="image"></a>
会在img src="image"后面停止,第8段成为 img src="image"而非/a
好了,正则表达式的用法已经基本会了,接下来就该编出我想要的效果了。首先要弄清楚ikariam页面的结构。
Chrome把世界地图的index.php下载到本机,经一番研究,发现有这样的数据(太多了,节选):
var map = new Map(44, 33);
map.handleMapData('{"request":{"x_min":30,"x_max"://……
真是天助我也。这个肯定就是worldmap的数据了。
仔细研究一下:
先在map上找一个岛,点上去,出现它的名字Lootios,在haddleMapData里查找,有这样的一段:
"45":{"46":["70","Lootios","1","3","7","7","6","16"],
回头一看,该岛的坐标正好是。后面的数据又是什么意思呢?先看到岛上有16个城,估计……
找到它旁边的Shaymios,有11城,查找到相应的数据:
"47":["74","Shaymios","3","4","7","10","7","11"],
好样的。把我要用的数据粘在这里,就不解释了:
"46":["73","Depuios","4","1","7","4","6","16"],
"44":{"45":["72","Zhexios","3","7","7","3","6","10"],
"43":["163","Chadoios","1","3","14","8","7","16"],
"45":["71","Phiyios","2","5","7","4","8","16"],
同样的方法发现:
(1)倒数第二个数字表示木头矿等级。
(2)名字后面的第一个数字是资源种类(1-Wine,2-Marble,3-Crystal,4-Sulfur)。
(3)名字后面的第二个数字是奇迹种类(1-
Hephaistos` Forge,2-
Hades` Holy Grove,3-
Demeter`s gardens, 4-
Temple of Athene,5-
Temple of Hermes,6-
Ares` Stronghold,7-
Temple of Poseidon,8-
Colossus)。
暂时就知道这些。更多的嘛,也有很重要的,但毕竟有替代方法,先放着不管了。
(今天早上登陆javaeye,发现和昨天一样也是登不进去,看来javaeye可能是每天早上例行维护了吧。这个也不关我事。
倒是今天下午我终于弄明白任务栏是为什么要卡死了。
因为每次卡死之后,除了任务栏之外,别的地方都工作正常,所以我把任务管理器置前,Opera打开,关掉屏幕。等吃完饭,打开屏幕,任务栏果然又卡死了。屏幕上提示svchost出错。于是,用任务管理器结束掉占内存最大的svchost,任务栏又活了。原来不是Opera的错,是svchost中毒了。那好吧,杀毒杀不掉,我以后就开着任务管理器工作,一旦看到svchost冒到顶上,就杀掉。)
如上文,只要能在我的服务器端拿到这个数组,就能解决所有问题了。但是,它是javascript,不知道能不能用fopen()读到。
好,这个script是写在发送给我的HTML文档里的,那我先试试能不能抓取script。用QQ空间最好了,因为它上面满是javascript。
在QQ空间的文档里搜索script,终于在最后发现了一段内嵌的script。就用它了。
首先,需要解决登录的问题,感觉无从下手。当然,从QQ面板上访问时,会给一个跳转地址,先试试它:
…………
真傻,明明就是跳转地址,拿来有何用。
试试http://user.qzone.qq.com/【号码 】吧
……怎么还是跳转了……不管了,先试试能不能取得数据:
<?php
$url="http://user.qzone.qq.com/419560202";
$html=file_get_contents($url,"r");
preg_match_all ("/(<a)(.*)(href=)([^>]*)(>)([^<]*)(<)([^>]*)(>)/", $html, $matches);
for ($i=0;$i<count($matches);$i++)
{
echo "|||".$matches[$i]."||".$matches[$i].$matches[$i]."||".$matches[$i]."||".$matches[$i]."<br>";
}
?>
页面一片空白。
换个网站吧,ikariam是没有跳转的,跳转问题以后再说。
啊哈!竟然在javaeye的首页上发现了内嵌的javascript,那就对不起了!
写正则。
<script type="text/javascript">……</script>
1:(<script)
2:([^>]*) //可以判断 script的种类
3:(>)
4:([^<]*) //script内容
5:(</script>) //当然,/得用转义字符\/
正则就是:/(<script)([^>]*)(>)([^<]*)(<\/script>)/
<?php
$url="http://www.iteye.com";
$html=file_get_contents($url,"r");
preg_match_all ("/(<script)([^>]*)(>)([^<]*)(<\/script>)/", $html, $matches);
for ($i=0;$i<count($matches);$i++)
{
echo "|||".$matches[$i]."||".$matches[$i]."<br>";
}
?>
OK,刷新,页面显示:
||| type="text/javascript"|| var marqueeing = true; function marquee(){ if(marqueeing) { var container=document.getElementById("advert_a9").getElementsByTagName("ul") container.appendChild(container.firstChild); } } setInterval("marquee()", 2000);
这不?就拿到了页面内嵌的js代码。
如果不是内嵌的呢?试一个,Chemspider网页里有这么一句:
<script type="text/javascript" language="javascript" src="/script.js"></script>
那我试试这个网址:
http://www.chemspider.com/script.js
……悲剧啊:failed to open stream: HTTP request failed!
看来,获取在另外的文件中的js,还得想个别的方法。试试fsockopen():
unable to connect to http://www.chemspider.com/script.js:80 (Unable to find the socket transport "http"
它还说:
did you forget to enable it when you configured PHP?
(看来,我可以用我的本机测试了。)
接下来,就该研究怎么样从服务器登陆QQ空间了,只有这样,我才能登陆ikariam,从而获得它的数据。
3天,终于又告一段落了。
页:
[1]