大家帮忙看一个爬虫抓取需要数据的正则

A. 待抓取的页面的 html

$str2 = <<<EOT
<div topClassName='top1' topSwitch='on'  productId='2256' productName='⑧北京汉奥汽配有限公司' class='productPicListForm' id='module406product2256' faiWidth='160' faiHeight='101' faiWidthOr='600' faiHeightOr='382'>
    <table id='formTable2256_module406' class='formTable' cellpadding='0' cellspacing='0'>

        <tr>
            <td class='imgDiv'>
                <table cellpadding='0' cellspacing='0'>
                    <tr>
                        <td>
                            <a hidefocus='true' href='h-pd-2256-2_406.html' target='_blank'>
                                <img alt='⑧北京汉奥汽配有限公司' title='' src='http://5003100.s21i-5.faiusr.com/2/ABUIABACGAAggsfqwAUotY6_qgUw2AQ4-gI!160x160.jpg'  />
                            </a>
                        </td>
                    </tr>
                </table>
            </td>

            <td style='' class='propList'>
                <div style='' class='propDiv productName    '>
                    <a class='fk-productName' hidefocus='true' href='h-pd-2256-2_406.html' target='_blank' title='⑧北京汉奥汽配有限公司'>⑧北京汉奥汽配有限公司</a>
                </div>

                <div class='propDiv productProp6    '>
                    <span class='propName fk-prop-name'>主营:</span>
                    <span class='propValue fk-prop-other'  style='text-decoration:none;font-family:微软雅黑;font-weight:normal;'>大众 新速腾 新迈腾 新桑塔纳 新捷达 CC 新帕萨特 新宝来 收事故车及残值(郭京汉)</span>
                </div>

                <div class='propDiv productProp4    '>
                    <span class='propName fk-prop-name'>地址:</span>
                    <span class='propValue fk-prop-other'  style='text-decoration:none;font-family:微软雅黑;font-weight:normal;'>城环城B-01号</span>
                </div>
            </td>
        </tr>

    </table>
</div>
EOT;

B. 我写的抓取正则:

<?php 
// 去掉开头和结尾多余的无用字符
$str2     = trim($str2);
// 去掉换行符
$str2     = preg_replace('/\r\n|\n\r|\r|\n/' , '' , $str2);
// 抓取正则

$reg_list = "/<div\s*topClassName\='top1'\s*topSwitch\='on'\s*productId\='(\d+)'\s*productName\='[\x7f-\xff]+'\s*class\='productPicListForm'\s*id\='[A-z0-9]+'\s*faiWidth\='\d+'\s*faiHeight\='\d+'\s*faiWidthOr\='\d+'\s*faiHeightOr\='\d+'>\s*<table\s*id\='\w+'\s*class\='formTable'\s*cellpadding\='\d*'\s*cellspacing\='\d+'>\s*<tr>\s*<td\s*class='imgDiv'>\s*<table\s*cellpadding='\d+'\s*cellspacing='\d+'>\s*<tr>\s*<td>\s*<a\s*hidefocus='true'\s*href='[A-z0-9\. \-_]+'\s*target='(_blank|_self)'>\s*<img\s*alt='([\x7f-\xff]+)'\s*title='[\x7f-\xffA-z0-9\-]*'\s*src='((http|https)\:\/\/[A-z0-9\.\/\!\-]+)'\s*\/>\s*<\/a>\s*<\/td>\s*<\/tr>\s*<\/table>\s*<\/td>\s*<td\s*style='[A-z0-9\:\-_#]*'\s*class='propList'>\s*<td\s*style\='[A-z0-9\:\-_#]*'\s*class\='propList'>\s*<div style='[A-z0-9\:\-_#]*' class='propDiv\s*productName\s*'>\s*<a\s*class\='fk-productName'\s*hidefocus\='true'\s*href\='([A-z0-9\-\._]+)'\s*target\='(_blank|_self)'\s*title\='[\x7f-\xff]+'>[\x7f-\xff]+<\/a>\s*<\/div>\s*<div\s*class\='propDiv\s*productProp\d*\s*'>\s*<span\s*class\='propName\s*fk-prop-name'>主营:<\/span>\s*<span\s*class='propValue\s*fk-prop-other'\s*style='[A-z0-9\x7f-\xff\: -_#;]*'>([\x7f-\xff ]+_-\.)<\/span>\s*<\/div>\s*<div\s*class='propDiv\s*productProp4\s*'>\s*<span\s*class\='propName\s*fk-prop-name'>地址:<\/span>\s*<span\s*class='propValue\s*fk-prop-other'\s*style='[A-z0-9\x7f-\xff\: -_#;]*'>([\x7f-\xff -_\.]+)<\/span>\s*<\/div>\s*<\/td>\s*<\/td>\s*<\/tr>\s*<\/table>\s*<\/div>/";

编辑器中显示(截图):

clipboard.png

之所以写成这么复杂是因为我要获取一下部分内容:

clipboard.png

关键点来了,那么复杂,根本无法调试正则让他正确的抓取到我要的内容,请问各位大牛是如何写这样复杂的正则,然后调试,直到能够抓取到自己想要的数据的??

阅读 4.2k
2 个回答

又要祭出symfony/dom-crawler大法了。DOM大法好,退正则保平安

composer.json

{
    "require": {
        "symfony/css-selector": "^3.2",
        "symfony/dom-crawler": "^3.2"
    }
}

a.php

<?php
/**
 * Created by PhpStorm.
 * User: shellus
 * Date: 2017/4/11
 * Time: 11:55
 */

use Symfony\Component\DomCrawler\Crawler;

require 'vendor/autoload.php';

$str2 = <<<EOT
<div topClassName='top1' topSwitch='on'  productId='2256' productName='⑧北京汉奥汽配有限公司' class='productPicListForm' id='module406product2256' faiWidth='160' faiHeight='101' faiWidthOr='600' faiHeightOr='382'>
    <table id='formTable2256_module406' class='formTable' cellpadding='0' cellspacing='0'>

        <tr>
            <td class='imgDiv'>
                <table cellpadding='0' cellspacing='0'>
                    <tr>
                        <td>
                            <a hidefocus='true' href='h-pd-2256-2_406.html' target='_blank'>
                                <img alt='⑧北京汉奥汽配有限公司' title='' src='http://5003100.s21i-5.faiusr.com/2/ABUIABACGAAggsfqwAUotY6_qgUw2AQ4-gI!160x160.jpg'  />
                            </a>
                        </td>
                    </tr>
                </table>
            </td>

            <td style='' class='propList'>
                <div style='' class='propDiv productName    '>
                    <a class='fk-productName' hidefocus='true' href='h-pd-2256-2_406.html' target='_blank' title='⑧北京汉奥汽配有限公司'>⑧北京汉奥汽配有限公司</a>
                </div>

                <div class='propDiv productProp6    '>
                    <span class='propName fk-prop-name'>主营:</span>
                    <span class='propValue fk-prop-other'  style='text-decoration:none;font-family:微软雅黑;font-weight:normal;'>大众 新速腾 新迈腾 新桑塔纳 新捷达 CC 新帕萨特 新宝来 收事故车及残值(郭京汉)</span>
                </div>

                <div class='propDiv productProp4    '>
                    <span class='propName fk-prop-name'>地址:</span>
                    <span class='propValue fk-prop-other'  style='text-decoration:none;font-family:微软雅黑;font-weight:normal;'>城环城B-01号</span>
                </div>
            </td>
        </tr>

    </table>
</div>
EOT;

$dom = new Crawler();

$dom->addHtmlContent($str2, 'UTF-8');

$imgSrc = $dom->filter('td.imgDiv')->filter('img')->attr('src');

$productName = $dom->filter('td.propList')->filter('div.productName>a')->text();

$productProp6 = $dom->filter('td.propList')->filter('div.productProp6>.propValue')->text();

$productProp4 = $dom->filter('td.propList')->filter('div.productProp4>.propValue')->text();

var_dump($imgSrc);
echo '<br>';
var_dump($productName);
echo '<br>';
var_dump($productProp6);
echo '<br>';
var_dump($productProp4);
echo '<br>';

输出

clipboard.png

DOM自然是更好选择,然正则也不见得做不到。

/alt=\'(?P<name>[^\']+)\'(?:.+?)?src=\'(?P<img>[^\']+)\'(?:.+?)?主营:(?:.+?)?\'>(?P<scope>[^<]+)(?:.+?)?地址:(?:.+?)?\'>(?P<address>[^<]+)/s
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题