草庐IT

php - 在 php 和 mysql 中从维基百科中提取内容

coder 2023-10-25 原文

我有一个网页,其中包含维基百科精选文章的所有链接,我提取了所有文章的标题、描述和关键字。但是我有一个问题,当网络爬虫开始提取文章的内容时,我的数据库中的字段描述和关键字仍然是空的。

如何提取维基百科文章的描述和关键字?

网络爬虫是用 php 和 mysql 编程的,这是实际的代码:

<?php
error_reporting(E_ALL | E_STRICT);
set_time_limit(0);
$server_link = mysql_connect("localhost", "root", "");
if (!$server_link) {
    die("Fall&oacute; la Conexi&oacute;n " . mysql_error());
}
$db_selected = mysql_select_db("test", $server_link);
if (!$db_selected) {
    die("No se pudo seleccionar la Base de Datos " . mysql_error());
}
@mysql_query("SET NAMES 'utf8'");
function storeLink($titulo, $descripcion, $url, $keywords) {
    $query = "INSERT INTO webs (webTitulo, webDescripcion, weburl, webkeywords) VALUES ('$titulo', '$descripcion', '$url', '$keywords')";
    mysql_query($query) or die('Error, falló la inserción de datos');
}
function extraer($url, $prof, $patron) {
    $userAgent = 'Interredu';
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(("Accept-Language: es-es,en")));
    curl_setopt($ch, CURLOPT_FAILONERROR, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_MAXREDIRS, 2);
    curl_setopt($ch, CURLOPT_AUTOREFERER, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $html = curl_exec($ch);
    saveUrl($url, $prof, $patron, $html);
    if (!$html) {
        echo "<br />cURL error number:" . curl_errno($ch);
        echo "<br />cURL error:" . curl_error($ch);
    }
    $dom = new DOMDocument();
    $dom->loadHTML($html);
    $xpath = new DOMXPath($dom);
    $hrefs = $xpath->evaluate("/html/body//a");
    for ($i = 0;$i < $hrefs->length;++$i) {
        $href = $hrefs->item($i);
        $url2 = $href->getAttribute('href');
        $var = strstr($url2, '#', true);
        if ($var !== false) {
            $url2 = $var;
        }

        if (strpos($url2, $patron) === false) {
            continue;
        }

        if ($url2 != $url && $url2 != '') {
            $busqueda = mysql_query("SELECT weburl FROM webs WHERE weburl='$url2'");
            $cantidad = mysql_num_rows($busqueda);
            if (1500 >= $prof && 0 == $cantidad) {
                extraer($url2, ++$prof, $patron);
            }
        }
    }
}
function saveUrl($url, $prof, $patron, $html) {
    $retorno = false;
    $pos = strpos($url, $patron);
    if ($prof >= 1) {
        preg_match_all("(<title>(.*)<\/title>)siU", $html, $title);
        $metas = get_meta_tags($url, 1);
        $titulo = html_entity_decode($title[1][0], ENT_QUOTES, 'UTF-8');
        $descripcion = isset($metas["description"])?$metas["description"] : '';
        $keywords = isset($metas["keywords"])?$metas["keywords"] : '';
    if (empty($descripcion)){
obtenerMetaDescription($html);
    }
    if (empty($keywords)){
preg_match_all("#<\s*h1[^>]*>[^<]+</h1>#is", $html, $encabezado);
    preg_match_all("#<\s*b[^>]*>[^<]+</b>#is", $html, $negrita);
    preg_match_all("#<\s*i[^>]*>[^<]+</i>#is", $html, $italica);
    foreach($encabezado[0] as $encabezado){
    $h1 = $encabezado;
    }
    foreach($negrita[0] as $negrita){
    $bold = $negrita;
    }
    foreach($italica[0] as $italica){
    $italic = $italica;
    }
    $keys = $bold." ".$h1." ".$italic." ";
    $keywords = substr(strip_tags($keys), 0, 200);
}
        storeLink($titulo, $descripcion, $url, $keywords, $prof);
        $retorno = true;
    }
    return $retorno;
}
function obtenerMetaDescription($text) {
    preg_match_all('#<p>(.*)</p>#Us', $html, $parraf);
    foreach($parraf[1] as $parraf){
    $descripcion = substr(strip_tags($parraf), 0, 200);
    }
    }
$url = "http://www.mywebsite.com/wikiarticles";
$patron = "http://es.wikipedia.org/wiki/";
$prof = 1500;
libxml_use_internal_errors(true);
extraer($url, 1, $patron);
$errores = libxml_get_errors();
libxml_clear_errors();
mysql_close();
?>

谢谢大家,问候。

最佳答案

这种情况下的一般方法

首先要做的是定位错误

  • 检查变量在不同位置的内容( $descripcion , $metas , $parraf )一些已知维基百科网址(您可以手动检查)
  • 这可以让您找出变量在哪里正确,哪里不正确

那么你可以得出以下可能的结论:

  • 代码中的每个变量都是正确的:您的 mysql-insert 方法中存在一些问题
  • 一些变量没有设置,即使它应该是:代码中特定位置的错误

这种方法如何适用于您的情况

  • 元描述似乎没有在维基百科上使用(至少在我看过的文章上)
  • 因此,应该调用 obtenerMetaDescription()
  • 所以我用一个像这样的小例子尝试了这个方法:

代码:

function obtenerMetaDescription($text) {
    preg_match_all('#<p>(.*)</p>#Us', $html, $parraf);
    foreach($parraf[1] as $parraf){
        $descripcion = substr(strip_tags($parraf), 0, 200);
        var_dump($descripcion);
    }
}

$html = file_get_contents('https://de.wikipedia.org/wiki/Ehrenmal_Marienfeld');
obtenerMetaDescription($html);
  • PHP 输出为:PHP Notice: Undefined variable: html in test.php on line 4

针对您情况的解决方案

您使用了 $html即使它被传递为 $text到功能。简单变量问题。

可能的其他问题

仔细检查分配给 $descripcion在同一个函数中。您分配 <p> 的内容至 $descripcionfor 循环 中。每次都用旧值覆盖旧值。我无法想象这是一种预期的行为。我猜您想实现以下两者之一:

  • 只取第一段:如果!empty(),只使用$parraf[1][0]
  • 将所有文本连接成一个大文本:使用 .=字符串连接运算符

关于php - 在 php 和 mysql 中从维基百科中提取内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13428541/

有关php - 在 php 和 mysql 中从维基百科中提取内容的更多相关文章

  1. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  2. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  3. ruby - 查找字符串中的内容类型(数字、日期、时间、字符串等) - 2

    我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s

  4. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  5. ruby-on-rails - Rails - 从命名路由中提取 HTTP 动词 - 2

    Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba

  6. ruby-on-rails - Ruby - 如何从 ruby​​ 上的 .pfx 文件中提取公钥、rsa 私钥和 CA key - 2

    我有一个.pfx格式的证书,我需要使用ruby​​提取公共(public)、私有(private)和CA证书。使用shell我可以这样做:#ExtractPublicKey(askforpassword)opensslpkcs12-infile.pfx-outfile_public.pem-clcerts-nokeys#ExtractCertificateAuthorityKey(askforpassword)opensslpkcs12-infile.pfx-outfile_ca.pem-cacerts-nokeys#ExtractPrivateKey(askforpassword)o

  7. ruby - 如何使用 Selenium Webdriver 根据 div 的内容执行操作? - 2

    我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption

  8. ruby-on-rails - 无法安装 mysql2 0.3.14 gem - 2

    我看到其他人也遇到过类似的问题,但没有一个解决方案对我有用。0.3.14gem与其他gem文件一起存在。我已经完全按照此处指示完成了所有操作:https://github.com/brianmario/mysql2.我仍然得到以下信息。我不知道为什么安装程序指示它找不到include目录,因为我已经检查过它存在。thread.h文件存在,但不在ruby​​目录中。相反,它在这里:C:\RailsInstaller\DevKit\lib\perl5\5.8\msys\CORE\我正在运行Windows7并尝试在Aptana3中构建我的Rails项目。我的Ruby是1.9.3。$gemin

  9. ruby - 如何在ruby中提取方括号内的内容 - 2

    我正在尝试提取方括号内的内容。到目前为止,我一直在使用它,它有效,但我想知道我是否可以直接在正则表达式中使用某些东西,而不是使用这个删除功能。a="Thisissuchagreatday[coolawesome]"a[/\[.*?\]/].delete('[]')#=>"coolawesome" 最佳答案 差不多。a="Thisissuchagreatday[coolawesome]"a[/\[(.*?)\]/,1]#=>"coolawesome"a[/(?"coolawesome"第一个依赖于提取组而不是完全匹配;第二个利用前瞻和

  10. ruby - 如何使用 ruby​​ mysql2 执行事务 - 2

    我已经开始使用mysql2gem。我试图弄清楚一些基本的事情——其中之一是如何明确地执行事务(对于批处理操作,比如多个INSERT/UPDATE查询)。在旧的ruby-mysql中,这是我的方法:client=Mysql.real_connect(...)inserts=["INSERTINTO...","UPDATE..WHEREid=..",#etc]client.autocommit(false)inserts.eachdo|ins|beginclient.query(ins)rescue#handleerrorsorabortentirelyendendclient.commi

随机推荐