Javascript可以读取任何网页的源代码吗?


76

我正在进行屏幕抓取,并且想要检索特定页面的源代码。

如何使用javascript做到这一点?请帮我。


这是一个类似的页面,您可能会得到答案,因为它解决了我获取HTML页面源代码的问题stackoverflow.com/questions/1367587/javascript-page-source-code
Asim Sajjad

7
@mikenvck为什么关于JavaScript的问题你甚至提到PHP?以下答案显示了如何使用JavaScript进行此操作。
corgrath 2012年

要获取链接的来源,您可能需要使用$.ajax外部链接。这里是解决方案- stackoverflow.com/a/18447625/2657601
otaxige_aol

1
没有一个答案是原生Javascript,它们都是基于jquery的。
ILikeTacos 2014年

1
jQuery是本机JavaScript。这只是JavaScript,您可以从jquery.com复制而不是从stackoverflow.com复制。
2015年

Answers:


111

简单的开始方法,尝试jQuery

$("#links").load("/Main_Page #jq-p-Getting-Started li");

jQuery Docs的更多内容

以更加结构化的方式进行屏幕抓取的另一种方法是使用YQL或Yahoo Query Language。它将返回构造为JSON或xml的抓取数据。
例如,
让我们抓取stackoverflow.com

select * from html where url="http://stackoverflow.com"

这样会给你一个JSON数组(我选择了那个选项)

 "results": {
   "body": {
    "noscript": [
     {
      "div": {
       "id": "noscript-padding"
      }
     },
     {
      "div": {
       "id": "noscript-warning",
       "p": "Stack Overflow works best with JavaScript enabled"
      }
     }
    ],
    "div": [
     {
      "id": "notify-container"
     },
     {
      "div": [
       {
        "id": "header",
        "div": [
         {
          "id": "hlogo",
          "a": {
           "href": "/",
           "img": {
            "alt": "logo homepage",
            "height": "70",
            "src": "http://i.stackoverflow.com/Content/Img/stackoverflow-logo-250.png",
            "width": "250"
           }
……..

这样做的好处是,您可以进行投影和where子句,最终使您得到的是已抓取的数据结构化的信息,而只有您需要的数据(最终使网络带宽大大减少),
例如

select * from html where url="http://stackoverflow.com" and
      xpath='//div/h3/a'

会得到你

 "results": {
   "a": [
    {
     "href": "/questions/414690/iphone-simulator-port-for-windows-closed",
     "title": "Duplicate: Is any Windows simulator available to test iPhone application? as a hobbyist who cannot afford a mac, i set up a toolchain kit locally on cygwin to compile objecti … ",
     "content": "iphone\n                simulator port for windows [closed]"
    },
    {
     "href": "/questions/680867/how-to-redirect-the-web-page-in-flex-application",
     "title": "I have a button control ....i need another web page to be redirected while clicking that button .... how to do that ? Thanks ",
     "content": "How\n                to redirect the web page in flex application ?"
    },
…..

现在只获取我们要做的问题

select title from html where url="http://stackoverflow.com" and
      xpath='//div/h3/a'

注意投影中的标题

 "results": {
   "a": [
    {
     "title": "I don't want the function to be entered simultaneously by multiple threads, neither do I want it to be entered again when it has not returned yet. Is there any approach to achieve … "
    },
    {
     "title": "I'm certain I'm doing something really obviously stupid, but I've been trying to figure it out for a few hours now and nothing is jumping out at me. I'm using a ModelForm so I can … "
    },
    {
     "title": "when i am going through my project in IE only its showing errors A runtime error has occurred Do you wish to debug? Line 768 Error:Expected')' Is this is regarding any script er … "
    },
    {
     "title": "I have a java batch file consisting of 4 execution steps written for analyzing any Java application. In one of the steps, I'm adding few libs in classpath that are needed for my co … "
    },
    {
……

编写查询后,它会为您生成一个网址

http://query.yahooapis.com/v1/public/yql?q=select%20title%20from%20html%20where%20url%3D%22http%3A%2F%2Fstackoverflow.com%22%20and%0A%20% 20%20%20%20%20xpath%3D'%2F%2Fdiv%2Fh3%2Fa'%0A%20%20%20%20&format = json&callback = cbfunc

就我们而言。

所以最终您最终会做这样的事情

var titleList = $.getJSON(theAboveUrl);

并玩。

美丽,不是吗?


4
出色,特别是因为在yahoo上暗示了穷人的解决方案,从而消除了使用代理来获取数据的需要。谢谢!!我冒昧地将最后一个演示链接修复为query.yahooapis.com:它在url编码中缺少%符号。很酷,这仍然有效!!
GitaarLAB

任何想法如何从amazon.in/Xiaomi-Redmi-4A-Grey-16GB/dp/…刮取图像和元描述?

query.yahooapis已于2019年1月退役。看起来真的很整洁,太可惜了我们现在不能使用它。看到推特在这里:twitter.com/ydn/status/1079785891558653952?
ref_src=twsrc%5Etfw

32

只要您通过域上的代理获取要访问的任何页面,就可以使用Javascript:

<html>
<head>
<script src="/js/jquery-1.3.2.js"></script>
</head>
<body>
<script>
$.get("www.mydomain.com/?url=www.google.com", function(response) { 
    alert(response) 
});
</script>
</body>

4
为什么需要基于域的代理?
拉文德拉纳特·阿基拉

3
由于同一个原产地政策
Ferdi265

真的很有趣。大概有一些代码要安装在服务器上以实现这一目标?
S Meaden

@ejbytes:实际上我认为node.js有一些模块。我以为OP要抓取网页。
S米登

您将获得“来自原点的“ null”已被CORS策略阻止:所请求的资源上没有“ Access-Control-Allow-Origin”标头。” 如果您不在同一个域中
Gerrit B '18

7

您可以简单地使用XmlHttp(AJAX)击中所需的URL,并且该URL中的HTML响应将在responseText属性中可用。如果不是同一域,则您的用户将收到一个浏览器警报,提示类似“此页面正在尝试访问其他域。是否要允许此域?”


3
不幸的是,您将不会收到任何警报,它只会阻止该请求
Alex

5

作为安全措施,Javascript无法从不同的域读取文件。尽管可能有一些奇怪的解决方法,但我会考虑使用另一种语言来完成此任务。



2

如果您绝对需要使用javascript,则可以使用ajax请求加载页面源。

请注意,使用javascript,您只能检索与请求页面位于同一域下的页面。


2

我使用了ImportIO。如果您与他们建立了一个帐户(免费),则可以使用它们从任何网站请求HTML。他们让您每年最多处理5万个请求。我没有花时间寻找替代方案,但是我敢肯定有一些替代方案。

在您的Javascript中,基本上您将只发出GET请求,如下所示:

var request = new XMLHttpRequest();

request.onreadystatechange = function() {
  jsontext = request.responseText;

  alert(jsontext);
}

request.open("GET", "https://extraction.import.io/query/extractor/THE_PUBLIC_LINK_THEY_GIVE_YOU?_apikey=YOUR_KEY&url=YOUR_URL", true);

request.send();

旁注:我在研究相同问题时发现了这个问题,因此其他人可能会觉得我的解决方案有所帮助。

更新:我创建了一个新产品,他们只允许我使用不到48小时,然后他们说我必须为此服务付费。如果您不付款,他们似乎很快就会关闭您的项目。我使用NodeJS和一个名为NightmareJS的库进行了自己的类似服务。您可以在此处查看其教程并创建自己的网络抓取工具。这比较容易。我没有尝试将其设置为可以向其发出请求的API。


1

jQuery不是做事的方式。在JavaScript中执行

var r = new XMLHttpRequest();
    r.open('GET', 'yahoo.comm', false);
    r.send(null); 
if (r.status == 200) { alert(r.responseText); }


0

您可以使用FileReader API来获取文件,然后在选择文件时,将网页的网址放入选择框中。使用此代码:

function readFile() {
    var f = document.getElementById("yourfileinput").files[0]; 
    if (f) {
      var r = new FileReader();
      r.onload = function(e) { 
        alert(r.result);
      }
      r.readAsText(f);
    } else { 
      alert("file could not be found")
    }
  }
}

0

您可以通过创建浏览器扩展程序甚至在Windows(HTML应用程序)中将文件另存为.hta来绕过同源策略。


0

尽管有许多相反的评论,但我相信使用简单的JavaScript可以克服相同的来源要求。

我并不是说以下内容是原始的,因为我相信不久前我在其他地方也看到过类似的内容。

我仅在Mac上使用Safari进行了测试。

以下演示获取基本标签中的页面并将其innerHTML移至新窗口。我的脚本添加了html标签,但是对于大多数现代浏览器,可以通过使用externalHTML避免这种情况。

<html>
<head>
<base href='http://apod.nasa.gov/apod/'>
<title>test</title>
<style>
body { margin: 0 }
textarea { outline: none; padding: 2em; width: 100%; height: 100% }
</style>
</head>
<body onload="w=window.open('#'); x=document.getElementById('t'); a='<html>\n'; b='\n</html>'; setTimeout('x.innerHTML=a+w.document.documentElement.innerHTML+b; w.close()',2000)">
<textarea id=t></textarea>
</body>
</html>

我将Safari 5.0.6和webkit修补程序一起使用,以将其更新为最新版本。您使用了哪个版本的Safari?发生了什么?
Neville Hillyer'3

8.0.3。除了一些错误(我没有记起)之外,什么都没有发生在控制台中。
昆丁

您使用的是哪个Safari,错误是什么?
内维尔·希尔耶

仍然是8.0.3,如果您真的要我重现测试用例:TypeError: undefined is not an object (evaluating 'w.document')
Quentin

关于您已成功执行的操作的最可能解释是,您发现了一个安全漏洞,这要归功于您积极使用的古老浏览器及其非官方补丁的某种组合。在大多数情况下,这不是实际用途。
Quentin

0
<script>
    $.getJSON('http://www.whateverorigin.org/get?url=' + encodeURIComponent('hhttps://example.com/') + '&callback=?', function (data) {
        alert(data.contents);
    });

</script>

包括jQuery并使用此代码获取其他网站的HTML。将example.com替换为您的网站

此方法涉及外部服务器获取网站HTML并将其发送给您。:)


0
javascript:alert("Inspect Element On");
javascript:document.body.contentEditable = 'true';
document.designMode='on'; 
void 0;
javascript:alert(document.documentElement.innerHTML); 

突出显示它并将其拖动到书签栏,然后在您想要编辑和查看当前站点源代码时单击它。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.