php实战开发网络爬虫,实现采集功能

网络爬虫简介

按照一定的规则自动抓取网上的内容。

php获取指定网页内容

file_get_contents函数

语法:

file_get_contents(要获取的资源地址)

获取网页内容的例子:

代码:

echo file_get_contents("http://www.phpfen.com");

获取https类型的网页内容

尝试获取:https://www.noxue.com 的内容

echo file_get_contents("https://www.noxue.com");

默认报错信息如下:

Warning: file_get_contents(): Unable to find the wrapper "https" - did you forget to enable it when you configured PHP? in F:\projects\php\test\index.php on line 3

Warning: file_get_contents(https://www.noxue.com): failed to open stream: No such file or directory in F:\projects\php\test\index.php on line 3

报错原因

https数据需要通过ssl协议加密传输,php默认没有开启ssl扩展,所以要开启ssl扩展。

如何开启ssl扩展

找到和phpfen.exe同目录下的php目录,然后找到php目录下的php.ini,在文件中找到这行;extension=php_openssl.dll,把前面的分号去掉,改成extension=./ext/php_openssl.dll。最后重新启动phpfen.exe

修改之前:

修改之后:

./ext/php_openssl.dll 是指定php扩展的路径,php_openssl.dll提供ssl加密解密相关的功能,在windows下php扩展是一个dll文件,在ext目录下。

file_put_contents函数

作用

file_put_contents() 函数把一个字符串写入文件中。

语法

file_put_contents(file,data,mode,context)

参数介绍

参数 描述

file 必需。规定要写入数据的文件。如果文件不存在,则创建一个新文件。

data 可选。规定要写入文件的数据。可以是字符串、数组或数据流。

mode 可选,规定如何打开/写入文件。可能的值:1.FILE_USE_INCLUDE_PATH:检查 filename 副本的内置路径。2.FILE_APPEND:在文件末尾以追加的方式写入数据。3.LOCK_EX:对文件上锁

context 可选。规定文件句柄的环境。context 是一套可以修改流的行为的选项。若使用 null,则忽略。

例子

echo file_put_contents("noxue.txt","www.noxue.com");

输出:13 也就是写入文件的字符个数。

默认这个函数会清空文件原来的内容,然后写入新的内容,如果要追加的话,把第三个参数设定为FILE_APPEND即可。

FILE_USE_INCLUDE_PATH 这个参数,表示文件会从include_path中寻找,可以通过echo get_include_path();查看include_path包含哪些路径。

正则表达式入门

元字符

表1.常用的元字符

代码 说明

. 匹配除换行符以外的任意字符

\w 匹配字母或数字或下划线或汉字

\s 匹配任意的空白符

\d 匹配数字

\b 匹配单词的开始或结束

^ 匹配字符串的开始

$ 匹配字符串的结束

字符转义

如果你想查找元字符本身的话,比如你查找.,或者*,就出现了问题:你没办法指定它们,因为它们会被解释成别的意思。这时你就得使用\来取消这些字符的特殊意义。因此,你应该使用\.和\*。当然,要查找\本身,你也得用\\

重复

表2.常用的限定符

代码/语法 说明

* 重复零次或更多次

+ 重复一次或更多次

? 重复零次或一次

{n} 重复n次

{n,} 重复n次或更多次

{n,m} 重复n到m次

反义

有时需要查找不属于某个能简单定义的字符类的字符。比如想查找除了数字以外,其它任意字符都行的情况,这时需要用到反义:

表3.常用的反义代码

代码/语法 说明

\W 匹配任意不是字母,数字,下划线,汉字的字符

\S 匹配任意不是空白符的字符

\D 匹配任意非数字的字符

\B 匹配不是单词开头或结束的位置

[^x] 匹配除了x以外的任意字符

[^aeiou] 匹配除了aeiou这几个字母以外的任意字符

例子:\S+匹配不包含空白符的字符串。

分组/注释

语法 说明

(exp) 匹配exp,并捕获文本到自动命名的组里

(?<name>exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name'exp)

(?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读

捕获例子:(\d{5,11}) 捕获文本中的qq号

捕获例子:(?<qq>\d{5,11}) 捕获文本中的qq号,并取名为qq

注释例子:2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)

贪婪与懒惰

当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。以这个表达式为例:a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。

有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?。这样.*?就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。现在看看懒惰版的例子吧:

a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)。

由于我们只需要用到正则表达式的部分知识,所以从 https://deerchao.net/tutorials/regex/regex.htm 截取了一些常用的知识。如果要深入,可以课后自己深入学习。

注意:30分钟入门正则那个工具可能是因为不是特意为php写的,有时候结果可能跟你用php执行后的结果不同,建议使用这个工具来测试正则:https://www.noxue.com/tool/regex.html

php使用正则表达式

preg_match

preg_match_all

php正则表达式例子

<?php

$str = "大家好,这是我的qq:30670835";

preg_match('#qq:([\d]+)#',$str,$mat);

print_r($mat);

?>

输出结果:

Array

(

    [0] => qq:30670835

    [1] => 30670835

)

主要看第一个参数

'#qq:([\d]+)#' 参数被#包含,其实用以下任意一个字符都可以。

`~!@#$%^&*-+*/

注意:被某个字符包含的正则中不能出现该字符,比如下方的代码就会报错

preg_match('#qq:#([\d]+)#', $str, $mat);因为正则被#包含,但是正则中包含了#,这种情况下,我们换一个字符包含就可以了,改成preg_match('/qq:#([\d]+)/', $str, $mat);就对了

分析下匹配结果返回的数组

Array

(

    [0] => qq:30670835

    [1] => 30670835

)

第1个元素表示该正则匹配的所有内容。

第2个元素表示第1个捕获的内容

捕获多个内容

<?php

$str = "<table><tr><td>不学网</td><td>www.noxue.com</td></tr></table>";

preg_match('#<td>(.*?)</td><td>(.*?)</td>#',$str,$mat);

print_r($mat);

输出:

Array

(

    [0] => <td>不学网</td><td>www.noxue.com</td>

    [1] => 不学网

    [2] => www.noxue.com

)

分组命名

例子:

<?php

$str = "<table><tr><td>不学网</td><td>www.noxue.com</td></tr></table>";

preg_match('#<td>(?<name>.*?)</td><td>(?<site>.*?)</td>#',$str,$mat);

print_r($mat);

输出:

Array

(

    [0] => <td>不学网</td><td>www.noxue.com</td>

    [name] => 不学网

    [1] => 不学网

    [site] => www.noxue.com

    [2] => www.noxue.com

)

php正则匹配所有

只要把上面代码中函数的preg_match改成preg_match_all即可:

<?php

$str = "大家好,这是我的qq:30670835 大家好,这是我的qq:30670835 ";

preg_match_all('#qq:([\d]+)#',$str,$mat);

print_r($mat);

?>

输出:注意是个二维数组

Array

(

    [0] => Array

        (

            [0] => qq:30670835

            [1] => qq:30670835

        )

    [1] => Array

        (

            [0] => 30670835

            [1] => 30670835

        )

)

php正则 修正符

模式修正符 说明

/u 表示按unicode(utf-8)匹配(主要针对多字节比如汉字)

/i 表示不区分大小写(如果表达式里面有 a, 那么 A 也是匹配对象)

/s 表示将字符串视为单行来匹配

/m 表示匹配多行

/x 将模式中的空白忽略.

例子:

<?php

$str = "<table><tr><TD>不学网</TD><td>www.noxue.com</td></tr></table>";

preg_match('#<td>(?<name>.*?)</td><td>(?<site>.*?)</td>#',$str,$mat);

print_r($mat);

上面的代码将会输出一个空数组,因为默认大小写不同也匹配不到。

但是我们可以通过模式修正符i来忽略大小写,例子如下:

<?php

$str = "<table><tr><TD>不学网</TD><td>www.noxue.com</td></tr></table>";

preg_match('#<td>(?<name>.*?)</td><td>(?<site>.*?)</td>#i',$str,$mat);

print_r($mat);

仅仅在正则表达式最后加上i就行了

以上代码则会匹配到正确的内容。

php实现采集指定内容

php正则与file_get_contents结合来实现



文章来源 不学网

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • php实现实时获取当天天气小工具 //获取天气预报网站的网页内容 $html = file_get_content...
    寻梦xunm阅读 1,224评论 0 4
  • 一、字符串操作 PHP开发中,我们遇到最多的可能就是字符串。 一个字符串 通过下面的3种方法来定义: 1、单引号 ...
    空谷悠阅读 739评论 1 6
  • 常用函数 var_dump() 函数返回数组的数据类型和值 unset() 释放 bool define(stri...
    Scallions_阅读 632评论 1 2
  • 一、数组 1、数组的声明:$arr = array(); 2、数组的初始化:PHP有两种数组:索引数组、关联数组。...
    yzw12138阅读 1,190评论 2 2
  • PHP 学习目录 ├─PHP视频教程 1 LAMP网站构建 │ ├─PHP教程 1.1.1 新版视频形式介绍│ ...
    曹渊说创业阅读 16,147评论 29 417