PDF 문서의 하이퍼링크 테스트

PDF 문서의 하이퍼링크 테스트

파일 의 하이퍼링크를 테스트할 수 있는 방법이 있습니까 pdf? 많은 수의 하이퍼링크가 포함된 파일이 있다고 가정합니다 . pdf해당 링크를 따라갈 때 받게 될 응답( 200= 확인, 404= 찾을 수 없음 등) 을 자동으로 테스트할 수 있습니까?

나는 웹페이지를 위한 그러한 도구가 존재한다는 것을 알고 있습니다(예:KLink상태, 또는 다음과 같은 웹 서비스로W3C의 체크링크) 하지만 에 해당하는 것이 있습니까 pdf? 내 생각에는 그런 것이 없는 것 같은데, tex파일에 상응하는 좋은 것이 있습니까? 일부 스크립트와 정규식 마술을 사용하면 이 작업을 수행할 수 있을 것 같지만 기존 솔루션이 있는지 궁금합니다.

\documentclass{article}
\usepackage{hyperref}

\begin{document}
\href{http://tex.stackexchange.com/test-404/}{This will give a 404}

\href{http://tex.stackexchange.com/}{This will give a 200}

\end{document}

답변1

컬을 설치합니다(apt-get을 사용하여 패키지를 설치한다고 가정).

sudo apt-get install curl

pdf 파일에 대해 다음을 수행하십시오.

cat document.pdf | grep -ao '[a-zA-Z]\+://[a-zA-Z.-]*[^)]\+' | while read LINE; do curl -o /dev/null --silent --head --write-out '%{http_code}' "$LINE";    echo " $LINE";  done

tex 파일에 대해 다음을 수행하십시오.

cat myfile.tex | grep -o '{[a-zA-Z]\+://[a-zA-Z.-]*[^}]\+}' | sed s/{// | sed s/}// | while read LINE; do curl -o /dev/null --silent --head --write-out '%{http_code}' "$LINE" echo " $LINE" done

즉시 테스트하려면 다음을 명령줄에 복사하여 붙여넣으세요.

echo "\documentclass{article}
\usepackage{hyperref}

\begin{document}
\href{http://tex.stackexchange.com/test-404/}{This will give a 404}

\href{http://tex.stackexchange.com/}{This will give a 200}

\end{document}" | grep -o '{[a-zA-Z]\+://[a-zA-Z.-]*[^}]\+}' | sed s/{// | sed s/}// | while read LINE; do
   curl -o /dev/null --silent --head --write-out '%{http_code}' "$LINE"
   echo " $LINE"
 done

자세한 내용은 다음을 참조하세요.

https://stackoverflow.com/questions/13611973/how-to-grep-for-a-url-in-a-file https://stackoverflow.com/questions/6136022/script-to-get-the-http-status-code-of-a-list-of-urls

답변2

Python을 사용하는 데 열려 있다면 이것으로 충분할 수 있습니다.

저는 pyPdf 및 urllib2 패키지와 함께 Python을 사용합니다. 논리는 다음과 같습니다. pyPdf.PdfFileReader로 PDF를 열고 반복합니다. 아래 함수에는 pdf열린 PDF 파일 개체가 있습니다.

def get_urls(pdf):
    badurls = list()
    links = list()
    url_checker = URLChecker() # a helper function to test the URL (urllib2)
    for pg in range(pdf.getNumPages()):
        page = pdf.getPage(pg)
        obj = page.getObject()

        for a in obj.get('/Annots', []):
            u = a.getObject()
            lnk = u['/A'].get('/D')
            url = u['/A'].get('/URI')
            if lnk:
                links.append(lnk)
            if url:
                urls.append(url)
                result, reason = url_checker.check(url)
                if not result:
                    badurls.append({'url':url, 'reason': '%r' % reason})

    anchors = pdf.getNamedDestinations().keys()
    badlinks = [x for x in links if x not in anchors]
    return urls, badurls, badlinks

url_checkerURL을 열고 오류가 있으면 를 반환합니다 (False, error_string). 그렇지 않으면 반환됩니다.(True, None)

따라서 프로세스가 끝나면 PDF에 있는 URL 목록, 열 수 없는 잘못된 URL(이유 포함), PDF에 있는 링크 목록 및 열리지 않는 링크의 하위 집합을 갖게 됩니다. 타겟 앵커가 있습니다.

url_checker에 대한 논리를 생략했지만 꽤 간단합니다. 해당 부분을 수행하는 방법 requests에는 여러 가지가 있습니다. urllib2.

답변3

Qt4와 Poppler를 사용하는 간단한 C++ 프로그램이 그 트릭을 수행할 것입니다. 나는 그것을 빠르게 스케치하고 일부 PDF에서 테스트했습니다. mailto: -protocol 및 기타 포트와 같은 이상한 링크에 대해 더 강력하게 만들기 위해 많이 조정할 수 있다고 생각합니다. 물론 나중에 구문 분석해야 하는 경우 출력 형식이 더 나을 수 있지만 이는 트릭을 수행합니다.

#include <QTcpSocket>
#include <QUrl>
#include <QByteArray>
#include <QList>
#include <poppler-qt4.h>
#include <QDebug>

  using namespace Poppler;

  QString urlGetStatus(const QUrl &url) {
    QString status;
    QTcpSocket socket;
    socket.connectToHost(url.host(), 80);
    if (socket.waitForConnected()) {
        socket.write("HEAD " + url.path().toUtf8() + " HTTP/1.1\r\n"
                     "Host: " + url.host().toUtf8() + "\r\n"
                     "\r\n");
        if (socket.waitForReadyRead()) {
                QByteArray bytes = socket.readAll();
                status = QString(bytes).mid(9, 3);
        }
    }
    return status;
  }

  int main(int argc, char *argv[]) {
    if(argc < 2) {
        return 1;
    }
    QString path = QString(argv[1]);
    Document *doc = Document::load(path);
    if(doc == NULL)
        return 1;
    QList<QUrl> urlList;
    for(int i = 0;i < doc->numPages(); i++) {        
        Page *p = doc->page(i);
        foreach(Link *li,p->links()) {
            if(li->linkType() == Link::Browse) {
                LinkBrowse *link = static_cast<LinkBrowse*>(li);
                urlList.append(QUrl(link->url()));
            }
        }
    }
    foreach(QUrl url, urlList) {
        QString stat = urlGetStatus(url);
        if(stat == "200") {
            qDebug() << url.toString() << "returned status 200";
        } else {
            qDebug() << url.toString() << " maybe not reachable status" << stat;
        }
    }
    return 0;
  }

저는 cmake 친구이기 때문에 이 CMakeLists.txt를 사용하여 컴파일했습니다.

cmake_minimum_required(VERSION 2.6)
project(qlinkextract)
set (CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/Modules/")

find_package(Qt4 REQUIRED QtCore QtNetwork)
include(${QT_USE_FILE})

find_package(Poppler REQUIRED)
include_directories(${POPPLER_QT_INCLUDE_DIR})

add_executable(qlinkextract main.cpp)
target_link_libraries(qlinkextract ${QT_LIBRARIES} ${POPPLER_QT_LIBRARIES})

Qt4 개발 패키지와 Poppler-Qt4 개발 패키지가 필요합니다. CMakeModules 디렉토리에 FindPoppler.cmake가 없으면 온라인으로 가서 가져오세요.

컴파일하려면 프로젝트 디렉토리에서 qlinkextract가 있는지 확인하십시오(다음과 같이 철자가 정확하게 입력되어야 함).

  • CMakeLists.txt(위 참조)
  • main.cpp (위 참조)
  • cmake/Modules/FindPoppler.cmake (어딘가에서 다운로드)
  • build/ (폴더는 선택사항입니다)

콘솔에서 빌드 폴더로 이동하여 다음을 입력하세요.

cmake ..
make

누락된 것이 있으면 누락된 패키지를 설치하세요.

몇 가지 출력 예:

"http://www.igi-global.com/chapter/ontology-based-multimedia-indexing/42895?camid=4v1" returned status 200 
"http://www.igi-global.com/chapter/ontology-based-multimedia-indexing/42895?camid=4v1" returned status 200 
"http://www.igi-global.com/e-resources/library-recommendation/?id=1" returned status 200 
"http://www.igi-global.com/chapter/towards-low-cost-energy-monitoring/112719?camid=4v1a" returned status 200 
"http://www.igi-global.com/article/algebraic-properties-of-rough-set-on-two-universal-sets-based-on-multigranulation/116046?camid=4v1a" returned status 200 
"http://www.igi-global.com/article/algebraic-properties-of-rough-set-on-two-universal-sets-based-on-multigranulation/116046?camid=4v1a" returned status 200 
"http://www.igi-global.com/article/fuzzy-decision-support-system-for-coronary-artery-disease-diagnosis-based-on-rough-set-theory/111313?camid=4v1a" returned status 200 
"http://www.igi-global.com/article/fuzzy-decision-support-system-for-coronary-artery-disease-diagnosis-based-on-rough-set-theory/111313?camid=4v1a" returned status 200 
"http://www.igi-global.com/chapter/optimization-model-identification-temperature-intelligent/74536?camid=4v1a" returned status 200 
"http://www.igi-global.com/chapter/optimization-model-identification-temperature-intelligent/74536?camid=4v1a" returned status 200 

관련 정보