我正在进行屏幕抓取,并希望检索特定页面的源代码。
如何用javascript实现这一目标?请帮帮我。
答案 0 :(得分:108)
简单的开始方式,尝试jQuery
$("#links").load("/Main_Page #jq-p-Getting-Started li");
以更加结构化的方式进行屏幕抓取的另一种方法是使用YQL or Yahoo Query Language.它将返回结构化为JSON或xml的抓取数据。
e.g。
让我们刮掉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"
}
……..
这样做的好处在于,您可以执行 投影以及 子句,这些条款最终会为您提供结构化的数据和仅数据的内容你需要(最终通过线路的带宽更少)
例如
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 … "
},
{
……
编写查询后,会为您生成一个网址
在我们的案例中。
所以最终你最终会做这样的事情
var titleList = $.getJSON(theAboveUrl);
玩它。
美丽 ,不是吗?
答案 1 :(得分:30)
可以使用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>
答案 2 :(得分:7)
您只需使用XmlHttp
(AJAX)点击所需的网址,即可在responseText
媒体资源中找到该网址的HTML响应。如果它不是同一个域,您的用户将收到一个浏览器提醒,上面写着“此页面正在尝试访问其他域名。您要允许这样做吗?”
答案 3 :(得分:6)
作为一项安全措施,Javascript无法读取不同域中的文件。虽然可能有一些奇怪的解决方法,但我会考虑使用不同的语言来完成这项任务。
答案 4 :(得分:3)
使用jquery
<html>
<head>
<script src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.js" ></script>
</head>
<body>
<script>
$.get("www.google.com", function(response) { alert(response) });
</script>
</body>
答案 5 :(得分:2)
如果您绝对需要使用javascript,则可以使用ajax请求加载页面源。
请注意,使用javascript,您只能使用请求页面检索位于同一域下的网页。
答案 6 :(得分: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的库创建了自己的类似服务。您可以看到他们的教程here并创建自己的网络抓取工具。这相对容易。我没有尝试将其设置为我可以向其提出请求的API。
答案 7 :(得分:2)
您可以使用fetch:
const URL = 'https://www.sap.com/belgique/index.html';
fetch(URL)
.then(res => res.text())
.then(text => {
console.log(text);
})
.catch(err => console.log(err));
答案 8 :(得分:0)
您可以生成XmlHttpRequest并请求页面,然后使用getResponseText()来获取内容。
答案 9 :(得分: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")
}
}
}
答案 10 :(得分:0)
您可以通过创建浏览器扩展程序或甚至在Windows(HTML应用程序)中将文件另存为.hta来绕过同源策略。
答案 11 :(得分:0)
尽管有许多相反的评论,但我相信用简单的JavaScript可以克服相同的起源要求。
我并不是说以下内容是原创的,因为我相信我在不久前曾在其他地方看到类似内容。
我只在Mac上用Safari测试过这个。
以下演示在基本标记中提取页面,并将其innerHTML移动到新窗口。我的脚本添加了html标签,但对于大多数现代浏览器,可以通过使用outerHTML来避免这种情况。
<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>
答案 12 :(得分: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并将其发送给您。 :)
答案 13 :(得分:0)
javascript:alert("Inspect Element On");
javascript:document.body.contentEditable = 'true';
document.designMode='on';
void 0;
javascript:alert(document.documentElement.innerHTML);
突出显示此内容并将其拖到您的书签栏,然后在您想要编辑和查看当前站点源代码时单击它。
答案 14 :(得分:0)
在Linux上
下载 slimerjs (slimerjs.org)
下载 Firefox 59 版
添加这个环境变量:export SLIMERJSLAUNCHER=/home/en/Letöltések/firefox59/firefox/firefox
在 slimerjs 下载页面上使用这个 .js 程序 (./slomerjs program.js):
var page = require('webpage').create();
page.open(
'http://www.google.com/search?q=görény',
function()
{
page.render('goo2.pdf');
phantom.exit();
}
);
使用 pdftotext 获取页面上的文本。
答案 15 :(得分:-1)
jquery不是做事的方式。 做purre javascript
var r = new XMLHttpRequest();
r.open('GET', 'yahoo.comm', false);
r.send(null);
if (r.status == 200) { alert(r.responseText); }