>  기사  >  웹 프론트엔드  >  코드 줄 아래에 메타태그 스크래핑 API 구축

코드 줄 아래에 메타태그 스크래핑 API 구축

DDD
DDD원래의
2024-10-21 16:33:02407검색

Whatsapp이나 Telegram과 같은 메시지 앱을 통해 내가 보내는 링크의 미리보기를 어떻게 볼 수 있는지 궁금한 적이 있나요?

Building a Meta Tags Scraping API in Under Lines of Code

Building a Meta Tags Scraping API in Under Lines of Code


Whatsapp 및 Telegram URL 미리보기

이 게시물에서는 URL을 받아들이고 이에 대한 메타 태그를 검색하는 스크래핑 API를 Deno로 구축하여 거의 모든 웹사이트에서 제목, 설명, 이미지 등과 같은 필드를 얻을 수 있습니다.

예:

curl https://metatags.deno.dev/api/meta?url=https://dev.to

이 결과를 제공합니다

{
  "last-updated": "2024-10-15 15:10:02 UTC",
  "user-signed-in": "false",
  "head-cached-at": "1719685934",
  "environment": "production",
  "description": "A constructive and inclusive social network for software developers. With you every step of your journey.",
  "keywords": "software development, engineering, rails, javascript, ruby",
  "og:type": "website",
  "og:url": "https://dev.to/",
  "og:title": "DEV Community",
  "og:image": "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8lvvnvil0m75nw7yi6iz.jpg",
  "og:description": "A constructive and inclusive social network for software developers. With you every step of your journey.",
  "og:site_name": "DEV Community",
  "twitter:site": "@thepracticaldev",
  "twitter:title": "DEV Community",
  "twitter:description": "A constructive and inclusive social network for software developers. With you every step of your journey.",
  "twitter:image:src": "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8lvvnvil0m75nw7yi6iz.jpg",
  "twitter:card": "summary_large_image",
  "viewport": "width=device-width, initial-scale=1.0, viewport-fit=cover",
  "apple-mobile-web-app-title": "dev.to",
  "application-name": "dev.to",
  "theme-color": "#000000",
  "forem:name": "DEV Community",
  "forem:logo": "https://media.dev.to/cdn-cgi/image/width=512,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png",
  "forem:domain": "dev.to",
  "title": "DEV Community"
}

정말 멋지지 않나요?

메타 태그와 왜 필요한가요?

메타 태그는 검색 엔진과 다른 클라이언트에 페이지에 대한 추가 정보를 제공하는 데 사용되는 HTML 요소입니다.
이러한 태그에는 일반적으로 정보 유형을 정의하는 이름 또는 속성 속성과 해당 정보의 값이 포함된 콘텐츠 속성이 포함됩니다. 다음은 두 개의 메타 태그의 예입니다.

<meta name="description" content="The <meta> HTML element represents metadata that cannot be represented by other HTML meta-related elements, like <base>, <link>, <script>, <style> or <title>.">
<meta property="og:image" content="https://developer.mozilla.org/mdn-social-share.cd6c4a5a.png">

첫 번째 태그는 페이지에 대한 설명을 제공하고, 두 번째 태그는 페이지가 소셜 미디어에 공유될 때 표시할 이미지를 정의하는 오픈 그래프 태그입니다.

메타 태그를 실제로 적용하는 방법 중 하나는 북마크 관리자를 구축하는 것입니다. 각 북마크의 제목, 설명, 이미지를 수동으로 추가하는 대신 메타 태그를 사용하여 북마크된 URL에서 이 정보를 자동으로 스크랩할 수 있습니다.

오픈 그래프

오픈 그래프는 원래 웹페이지 내 메타데이터 사용을 표준화하여 페이지 콘텐츠를 표시하기 위해 Facebook에서 만든 인터넷 프로토콜로, 소셜 네트워크에서 풍부한 링크 미리 보기를 생성하는 데 도움이 됩니다.
자세한 내용은 여기를 참조하세요.

왜 데노인가?

  1. Deno에는 보안 기본값이 있습니다. 즉, 파일, 네트워크 및 환경 액세스에 대한 명시적인 권한이 필요하므로 보안 취약점의 위험이 줄어듭니다.
  2. Deno는 웹 표준을 기반으로 구축되었으며 ES 모듈을 사용하고 독점 API 대신 웹 플랫폼 API(예: 가져오기)를 사용하는 것을 목표로 하여 Deno 코드를 브라우저에서 작성하는 코드와 매우 유사하게 만들지만 여전히 일부 사양이 있습니다. 브라우저와의 편차.
  3. Deno에는 TypeScript 지원이 내장되어 있어 빌드 단계 없이 TypeScript 코드를 작성할 수 있습니다.
  4. Deno에는 HTTP 서버, 파일 시스템 작업 등과 같은 일반적인 작업을 위한 모듈이 포함된 표준 라이브러리가 함께 제공됩니다.
  5. Deno는 Linter, Formatter 및 Test Runner를 제공하므로 타사 패키지나 도구에 의존하지 않고 플랫폼을 사용할 수 있으므로 Javascript 개발을 위한 올인원 도구가 됩니다.
  6. Deno는 전 세계적으로 분산된 서버리스 JavaScript/Typescript 애플리케이션을 위한 확장 가능한 플랫폼인 Deno Deploy를 제공하여 대기 시간을 최소화하고 가동 시간을 최대화합니다.

우리가 구축 중인 API는 메타 태그를 가져오고 구문 분석하는 기능과 HTTP 요청에 응답하는 API 서버라는 두 부분으로 구성됩니다.

메타 태그 가져오기

Deno Deploy로 이동하여 로그인하는 것부터 시작하겠습니다.
로그인 후 "새 놀이터"를 클릭하세요
Building a Meta Tags Scraping API in Under Lines of Code
이것이 우리에게 Hello World 시작점을 제공할 것입니다.
이제 URL을 허용하고 Fetch API를 사용하여 요청된 URL의 HTML을 가져온 다음 이를 HTML 구문 분석용 패키지(deno-dom)에 전달하는 getMetaTags라는 함수를 추가하겠습니다.
프로젝트에 deno-dom을 추가하려면 jsr 패키지 관리자를 사용할 수 있습니다:

curl https://metatags.deno.dev/api/meta?url=https://dev.to

이제 Fetch API를 사용하여 HTML을 텍스트로 가져옵니다.

{
  "last-updated": "2024-10-15 15:10:02 UTC",
  "user-signed-in": "false",
  "head-cached-at": "1719685934",
  "environment": "production",
  "description": "A constructive and inclusive social network for software developers. With you every step of your journey.",
  "keywords": "software development, engineering, rails, javascript, ruby",
  "og:type": "website",
  "og:url": "https://dev.to/",
  "og:title": "DEV Community",
  "og:image": "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8lvvnvil0m75nw7yi6iz.jpg",
  "og:description": "A constructive and inclusive social network for software developers. With you every step of your journey.",
  "og:site_name": "DEV Community",
  "twitter:site": "@thepracticaldev",
  "twitter:title": "DEV Community",
  "twitter:description": "A constructive and inclusive social network for software developers. With you every step of your journey.",
  "twitter:image:src": "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8lvvnvil0m75nw7yi6iz.jpg",
  "twitter:card": "summary_large_image",
  "viewport": "width=device-width, initial-scale=1.0, viewport-fit=cover",
  "apple-mobile-web-app-title": "dev.to",
  "application-name": "dev.to",
  "theme-color": "#000000",
  "forem:name": "DEV Community",
  "forem:logo": "https://media.dev.to/cdn-cgi/image/width=512,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png",
  "forem:domain": "dev.to",
  "title": "DEV Community"
}

HTML을 가져온 후 deno-dom을 사용하여 구문 분석한 다음 querySelectorAll과 같은 표준 DOM 함수를 사용하여 모든 메타 HTML 요소를 가져오고 이를 반복한 다음 getAttribute를 사용하여 각 항목의 이름, 속성 및 콘텐츠를 가져올 수 있습니다. 해당 태그 중:

<meta name="description" content="The <meta> HTML element represents metadata that cannot be represented by other HTML meta-related elements, like <base>, <link>, <script>, <style> or <title>.">
<meta property="og:image" content="https://developer.mozilla.org/mdn-social-share.cd6c4a5a.png">

마지막으로 API의 필드로 추가하려면 페이지 요소를 사용하세요.<br> </p> <pre class="brush:php;toolbar:false">import { DOMParser, Element } from "jsr:@b-fuze/deno-dom"; </pre> <p>정확히는 메타 태그는 아니지만 유용한 필드라고 생각하므로 어쨌든 API의 일부가 될 것입니다. :)</p> <p>최종 getMetaTags 함수는 다음과 같습니다.<br> </p> <pre class="brush:php;toolbar:false"> const headers = new Headers(); headers.set("accept", "text/html,application/xhtml+xml,application/xml"); const res = await fetch(url, { headers }); const html = await res.text(); </pre> <h2> 서버 </h2> <p>단순화를 위해 저는 단순한 Deno.serve() 호출인 Deno에 내장된 http 서버를 사용하기로 결정했습니다.<br> deno는 웹 표준을 기반으로 구축되었기 때문에 Fetch API에 내장된 Response 개체를 사용하여 요청에 응답할 수 있습니다.<br> </p> <pre class="brush:php;toolbar:false">curl https://metatags.deno.dev/api/meta?url=https://dev.to </pre> <p>우리 서버는 요청 URL을 구문 분석하고 /api/meta 경로에 대한 GET 요청을 받았는지 확인한 후 우리가 만든 getMetaTags 함수를 호출한 다음 메타 태그를 응답 본문으로 반환합니다.</p> <p>또한 두 개의 헤더를 추가합니다. 첫 번째는 클라이언트가 응답에서 받는 데이터 종류를 아는 데 필요한 Content-Type이며, 우리의 경우 JSON 응답입니다.</p> <p>두 번째 헤더는 API가 특정 출처의 요청을 수락할 수 있도록 하는 Access-Control-Allow-Origin입니다. 이 경우에는 모든 출처를 허용하기 위해 "*"를 선택했지만 다음의 요청만 수락하도록 변경하고 싶을 수도 있습니다. 프런트엔드의 출처입니다.<br> CORS 헤더는 브라우저의 요청에만 영향을 미칩니다. 즉, 브라우저는 헤더에 지정된 원본에 따라 요청을 차단하지만 서버에서 API를 직접 호출하는 것은 여전히 ​​가능합니다. 여기에서 CORS에 대해 자세히 알아보세요.</p> <p>이제 "저장 및 배포"를 클릭할 수 있습니다<br> <img src="https://img.php.cn/upload/article/000/000/000/172949959089268.jpg" alt="Building a Meta Tags Scraping API in Under Lines of Code"><br> 그런 다음 deno 배포가 플레이그라운드에 코드를 배포할 때까지 기다립니다.<br> <img src="https://img.php.cn/upload/article/000/000/000/172949959198494.jpg" alt="Building a Meta Tags Scraping API in Under Lines of Code"><br> 오른쪽 상단에 있는 URL은 플레이그라운드의 URL입니다. 이를 복사하고 /api/meta?url=https://dev.to를 추가하여 실제로 작동하는지 확인하세요. URL은 https://metatags.deno.dev와 유사해야 합니다. /api/meta?url=https://dev.to<br> 이제 dev.to의 메타 태그로 응답하는 API를 볼 수 있습니다!<br> <img src="https://img.php.cn/upload/article/000/000/000/172949959294656.jpg" alt="Building a Meta Tags Scraping API in Under Lines of Code"></p> <h2> 전개 </h2> <p>Deno 배포 플레이그라운드를 사용한다는 것은 귀하의 코드가 기술적으로 이미 배포되었으며 공개되어 누구나 액세스할 수 있음을 의미합니다.<br> 우리가 구축하고 있는 것과 같은 간단한 API의 경우 단일 파일 플레이그라운드로 충분할 수 있지만 대부분의 경우 프로젝트를 더 확장하고 싶습니다. 이를 위해 Deno 배포의 Github 내보내기를 사용하여 적절한 코드 저장소를 만들 수 있습니다. 새로운 코드 푸시 시 자동 빌드를 지원하는 API:<br> <img src="https://img.php.cn/upload/article/000/000/000/172949959428755.jpg" alt="Building a Meta Tags Scraping API in Under Lines of Code"><br> 또는 놀이터 설정에서:<br> <img src="https://img.php.cn/upload/article/000/000/000/172949959544011.jpg" alt="Building a Meta Tags Scraping API in Under Lines of Code"></p> <h2> 주의사항 </h2> <p>이 게시물에 제시된 스크래핑 방법은 서버에서 반환된 html 파일에 메타 태그가 있는 웹사이트에서만 작동합니다. 즉, 서버에서 렌더링되거나 사전 렌더링된 사이트가 적절한 결과를 반환할 가능성이 더 높으며, 단일 페이지 앱도 가능한 한 작동할 수 있습니다. 메타 태그는 런타임이 아닌 빌드 시간에 설정되기 때문입니다.</p> <h2> 결론 </h2> <p>우리는 Deno를 사용하여 API를 구축하고 배포하는 것이 얼마나 빠르고 간단한지 시연했으며, 메타 태그를 살펴보고, Fetch API, DOM 파서 및 Deno의 내장 서버를 사용하여 API를 구축하는 방법을 설명했습니다. 40줄 미만의 코드로 메타태그 스크래핑 API를 제공합니다.</p> <p>이 게시물에 구축된 프로젝트를 보려면 Deno 배포 플레이그라운드를 확인하세요. (오른쪽 URL 표시줄에 /api/meta?url=https://dev.to를 추가해야 볼 수 있습니다.) 예시 응답) 또는 이 github 저장소.</p> <hr> <h2> 다음에는 무엇을 만들 것인가? </h2> <p>이 게시물이 여러분이 메타 태그와 Deno의 힘을 탐구하는 데 영감을 주었기를 바랍니다! 자신만의 API 버전을 구축하거나 북마크 관리자와 같은 프로젝트에 통합해 보세요. </p> <p>막히거나 질문이 있거나 자신이 만든 것을 자랑하고 싶으신가요? 아래에 댓글을 달거나 Twitter/X에서 저와 연결하세요. 여러분의 의견을 듣고 싶습니다! </p> <p>여기에서 40줄 미만의 코드로 반응 상태 관리 라이브러리를 구축하는 방법에 대한 이전 게시물을 확인하세요.</p> <p>위 내용은 코드 줄 아래에 메타태그 스크래핑 API 구축의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!</p></div><div class="nphpQianMsg"><a href="javascript:void(0);">JavaScript</a> <a href="javascript:void(0);">typescript</a> <a href="javascript:void(0);">json</a> <a href="javascript:void(0);">html</a> <a href="javascript:void(0);">Object</a> <a href="javascript:void(0);">if</a> <a href="javascript:void(0);">for</a> <a href="javascript:void(0);">while</a> <a href="javascript:void(0);">include</a> <a href="javascript:void(0);">try</a> <a href="javascript:void(0);">using</a> <a href="javascript:void(0);">public</a> <a href="javascript:void(0);">finally</a> <a href="javascript:void(0);">Attribute</a> <a href="javascript:void(0);">Property</a> <a href="javascript:void(0);">copy</a> <a href="javascript:void(0);">function</a> <a href="javascript:void(0);">dom</a> <a href="javascript:void(0);">this</a> <a href="javascript:void(0);">display</a> <a href="javascript:void(0);">github</a> <a href="javascript:void(0);">serverless</a> <a href="javascript:void(0);">kind</a> <a href="javascript:void(0);">http</a> <a href="javascript:void(0);">https</a> <a href="javascript:void(0);">Access</a><div class="clear"></div></div><div class="nphpQianSheng"><span>성명:</span><div>본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.</div></div></div><div class="nphpSytBox"><span>이전 기사:<a class="dBlack" title="jQuery/JavaScript에서 밀리초를 읽을 수 있는 날짜로 변환하는 방법은 무엇입니까?" href="http://m.php.cn/ko/faq/1796638584.html">jQuery/JavaScript에서 밀리초를 읽을 수 있는 날짜로 변환하는 방법은 무엇입니까?</a></span><span>다음 기사:<a class="dBlack" title="jQuery/JavaScript에서 밀리초를 읽을 수 있는 날짜로 변환하는 방법은 무엇입니까?" href="http://m.php.cn/ko/faq/1796638593.html">jQuery/JavaScript에서 밀리초를 읽을 수 있는 날짜로 변환하는 방법은 무엇입니까?</a></span></div><div class="nphpSytBox2"><div class="nphpZbktTitle"><h2>관련 기사</h2><em><a href="http://m.php.cn/ko/article.html" class="bBlack"><i>더보기</i><b></b></a></em><div class="clear"></div></div><ins class="adsbygoogle" style="display:block" data-ad-format="fluid" data-ad-layout-key="-6t+ed+2i-1n-4w" data-ad-client="ca-pub-5902227090019525" data-ad-slot="8966999616"></ins><script> (adsbygoogle = window.adsbygoogle || []).push({}); </script><ul class="nphpXgwzList"><li><b></b><a href="http://m.php.cn/ko/faq/1609.html" title="Bootstrap 목록 그룹 구성 요소에 대한 심층 분석" class="aBlack">Bootstrap 목록 그룹 구성 요소에 대한 심층 분석</a><div class="clear"></div></li><li><b></b><a href="http://m.php.cn/ko/faq/1640.html" title="JavaScript 함수 커링에 대한 자세한 설명" class="aBlack">JavaScript 함수 커링에 대한 자세한 설명</a><div class="clear"></div></li><li><b></b><a href="http://m.php.cn/ko/faq/1949.html" title="JS 비밀번호 생성 및 강도 감지의 전체 예(데모 소스 코드 다운로드 포함)" class="aBlack">JS 비밀번호 생성 및 강도 감지의 전체 예(데모 소스 코드 다운로드 포함)</a><div class="clear"></div></li><li><b></b><a href="http://m.php.cn/ko/faq/2248.html" title="Angularjs는 WeChat UI(weui)를 통합합니다." class="aBlack">Angularjs는 WeChat UI(weui)를 통합합니다.</a><div class="clear"></div></li><li><b></b><a href="http://m.php.cn/ko/faq/2351.html" title="JavaScript를 사용하여 중국어 번체와 중국어 간체 간을 빠르게 전환하는 방법과 중국어 간체와 중국어 번체 간 전환을 지원하는 웹사이트의 요령_javascript 기술" class="aBlack">JavaScript를 사용하여 중국어 번체와 중국어 간체 간을 빠르게 전환하는 방법과 중국어 간체와 중국어 번체 간 전환을 지원하는 웹사이트의 요령_javascript 기술</a><div class="clear"></div></li></ul></div></div><ins class="adsbygoogle" style="display:block" data-ad-format="autorelaxed" data-ad-client="ca-pub-5902227090019525" data-ad-slot="5027754603"></ins><script> (adsbygoogle = window.adsbygoogle || []).push({}); </script><div class="nphpFoot"><div class="nphpFootBg"><ul class="nphpFootMenu"><li><a href="http://m.php.cn/ko/"><b class="icon1"></b><p>집</p></a></li><li><a href="http://m.php.cn/ko/course.html"><b class="icon2"></b><p>강의</p></a></li><li><a href="http://m.php.cn/ko/wenda.html"><b class="icon4"></b><p>Q&A</p></a></li><li><a href="http://m.php.cn/ko/login"><b class="icon5"></b><p>나의</p></a></li><div class="clear"></div></ul></div></div><div class="nphpYouBox" style="display: none;"><div class="nphpYouBg"><div class="nphpYouTitle"><span onclick="$('.nphpYouBox').hide()"></span><a href="http://m.php.cn/ko/"></a><div class="clear"></div></div><ul class="nphpYouList"><li><a href="http://m.php.cn/ko/"><b class="icon1"></b><span>집</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/ko/course.html"><b class="icon2"></b><span>강의</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/ko/article.html"><b class="icon3"></b><span>기사</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/ko/wenda.html"><b class="icon4"></b><span>Q&A</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/ko/dic.html"><b class="icon6"></b><span>사전</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/ko/course/type/99.html"><b class="icon7"></b><span>수동</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/ko/xiazai/"><b class="icon8"></b><span>다운로드</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/ko/faq/zt" title="주제"><b class="icon12"></b><span>주제</span><div class="clear"></div></a></li><div class="clear"></div></ul></div></div><div class="nphpDing" style="display: none;"><div class="nphpDinglogo"><a href="http://m.php.cn/ko/"></a></div><div class="nphpNavIn1"><div class="swiper-container nphpNavSwiper1"><div class="swiper-wrapper"><div class="swiper-slide"><a href="http://m.php.cn/ko/" >집</a></div><div class="swiper-slide"><a href="http://m.php.cn/ko/article.html" class="hover">기사</a></div><div class="swiper-slide"><a href="http://m.php.cn/ko/wenda.html" >Q&A</a></div><div class="swiper-slide"><a href="http://m.php.cn/ko/course.html" >강의</a></div><div class="swiper-slide"><a href="http://m.php.cn/ko/faq/zt" >주제</a></div><div class="swiper-slide"><a href="http://m.php.cn/ko/xiazai" >다운로드</a></div><div class="swiper-slide"><a href="http://m.php.cn/ko/game" >게임</a></div><div class="swiper-slide"><a href="http://m.php.cn/ko/dic.html" >사전</a></div><div class="clear"></div></div></div><div class="langadivs" ><a href="javascript:;" class="bg4 bglanguage"></a><div class="langadiv" ><a onclick="javascript:setlang('zh-cn');" class="language course-right-orders chooselan " href="javascript:;"><span>简体中文</span><span>(ZH-CN)</span></a><a onclick="javascript:setlang('en');" class="language course-right-orders chooselan " href="javascript:;"><span>English</span><span>(EN)</span></a><a onclick="javascript:setlang('zh-tw');" class="language course-right-orders chooselan " href="javascript:;"><span>繁体中文</span><span>(ZH-TW)</span></a><a onclick="javascript:setlang('ja');" class="language course-right-orders chooselan " href="javascript:;"><span>日本語</span><span>(JA)</span></a><a onclick="javascript:;" class="language course-right-orders chooselan chooselanguage" href="javascript:;"><span>한국어</span><span>(KO)</span></a><a onclick="javascript:setlang('ms');" class="language course-right-orders chooselan " href="javascript:;"><span>Melayu</span><span>(MS)</span></a><a onclick="javascript:setlang('fr');" class="language course-right-orders chooselan " href="javascript:;"><span>Français</span><span>(FR)</span></a><a onclick="javascript:setlang('de');" class="language course-right-orders chooselan " href="javascript:;"><span>Deutsch</span><span>(DE)</span></a></div></div><script> var swiper = new Swiper('.nphpNavSwiper1', { slidesPerView : 'auto', observer: true,//修改swiper自己或子元素时,自动初始化swiper observeParents: true,//修改swiper的父元素时,自动初始化swiper }); </script></div></div><!--顶部导航 end--><script>isLogin = 0;</script><script type="text/javascript" src="/static/layui/layui.js"></script><script type="text/javascript" src="/static/js/global.js?4.9.47"></script></div><script src="https://vdse.bdstatic.com//search-video.v1.min.js"></script><link rel='stylesheet' id='_main-css' href='/static/css/viewer.min.css' type='text/css' media='all'/><script type='text/javascript' src='/static/js/viewer.min.js?1'></script><script type='text/javascript' src='/static/js/jquery-viewer.min.js'></script><script>jQuery.fn.wait = function (func, times, interval) { var _times = times || -1, //100次 _interval = interval || 20, //20毫秒每次 _self = this, _selector = this.selector, //选择器 _iIntervalID; //定时器id if( this.length ){ //如果已经获取到了,就直接执行函数 func && func.call(this); } else { _iIntervalID = setInterval(function() { if(!_times) { //是0就退出 clearInterval(_iIntervalID); } _times <= 0 || _times--; //如果是正数就 -- _self = $(_selector); //再次选择 if( _self.length ) { //判断是否取到 func && func.call(_self); clearInterval(_iIntervalID); } }, _interval); } return this; } $("table.syntaxhighlighter").wait(function() { $('table.syntaxhighlighter').append("<p class='cnblogs_code_footer'><span class='cnblogs_code_footer_icon'></span></p>"); }); $(document).on("click", ".cnblogs_code_footer",function(){ $(this).parents('table.syntaxhighlighter').css('display','inline-table');$(this).hide(); }); $('.nphpQianCont').viewer({navbar:true,title:false,toolbar:false,movable:false,viewed:function(){$('img').click(function(){$('.viewer-close').trigger('click');});}}); </script></body></html>