2015-05-20 3 views
2

Я хочу проанализировать (с Javascript или JSoup) веб-сайт. Моя проблема в том, что я не знал, как получить доступ к требуемым данным, потому что в этом файле практически нет идентификаторов.Анализ данных из HTML без идентификаторов

У меня есть что-то вроде:

  <div id content> 
<table> 
<tbody> 
<tr> 
<td align > 
<div style=> 
<table> 
<tbody> 
<tr></tr> 
<tr></tr> 
    <tr> 

    <td> 
    <br></br> 
    <h2><div class=""></div>Related</h2> 

    Adaptation: 
    <a href="/link">nameOfBook</a> 
    <br></br> 

    Prequel: 
    <a href="/link2">nameOfBook2</a> 
    <br></br> 

    Other: 

    <a href="link3"></a> 
    <br></br> 
    <br></br> 
    <h2></h2> 
    <table width0"></table> 
    ..........many tables and a..... 
    </tr> 
        </tbody> 
       </table> 
      </div> 
     </td> 
    </tr> 
</tbody> 

Хотелось бы надеяться его понятным, сайт довольно большой. Я хочу материал после родственника. Так что я хочу, чтобы Sequel был связан с тремя именами и их ссылками. И тогда имя преквела3.

На данный момент я получаю #content, тогда я получаю массив со всеми тегами h2 и проверяю второго ребенка, если он равен «Связанный». Затем я получаю родительский (td) и перебираю все «а». В этом одном td более 200 a's.

Мой план состоял в том, чтобы перебирать их и проверить, есть ли перед этим «а» термин (приквел, сиквел или адаптация), но это звучит немного сложно.

Или я мог разобрать все между двумя тегами h2, потому что он всегда там. Или, я мог проверить ссылку, потому что у желаемых всегда была одна и та же структура. Итак, найдите эту структуру, а затем перейдите к родительскому объекту и проверьте, что это за термин.

Кто-нибудь может мне помочь? Во всем документе нет идентификаторов или имен. Я уверен, что я могу найти обходное решение для этого, но это будет слишком сложно и с некоторыми знаниями JS легко получить.

ОБНОВЛЕНИЕ:

подмигнули не известно, сколько Приквел/Sequel независимо Метки будут там. Единственное, что я действительно знал, это то, что будет «Связанный» текст между двумя h2-тегами, а следующее начало h2 - это начало чего-то нового.

И изменил приведенный выше пример: теперь это правильная структура, #content снова находится в div, но я думаю, что это не важно, потому что я могу напрямую обращаться к контенту.

+0

Покажите нам свою JS, было бы легче понять и помочь;). – Bladepianist

+2

советую использовать ** DOM ** и ** XPath **. http://stackoverflow.com/questions/6466831/selecting-element-from-dom-with-javascript-and-xpath – Brcinho

+0

Вы уверены, что ваша разметка '' вне таблицы? – Camusensei

ответ

2

Вы можете использовать document.querySelector или document.querySelectorAll и относительный выбор соответствующего элемента.

Например: выбрать первые три a теги в сНу [ID = «содержание»]

var allAnchorsInDiv = document.querySelectorAll("div[id='content'] a"); //Basically this is an array of anchors. 
//select anchors from array. 

Если у вас нет каких-либо Идентификаторы вообще, то вы, вероятно, следует использовать относительный путь (что-то вроде Xpath или CSS-селектора).

С помощью селектора CSS вы будете использовать что-то вроде этого,

document.querySelectorAll('body>div:first-of-type>a'); 

Или вы можете использовать XPath см w3school

Примечание: Если вы хотите вещи немного легче вы можете даже использовать JQuery для выполните то же самое.

Update:

Таким образом, для ваших потребностей, вы должны сделать это.

  1. Выберите текстовый узел с текстом.
  2. Найдите узловые узловые узлы рядом с ним.

Таким образом,

var myKeyTerm = "Sequel"; //Set your keyterm here. 
var myAnchorTags = []; 
var myTextNode = document.evaluate("//text()[contains(., '"+myKeyTerm +"')]" ,document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; 
if(myTextNode) { 
    var nextNode = myTextNode; 
    do { 
     nextNode = nextNode.nextSibling; 
     if(nextNode && nextNode.nodeName == "A") { 
      myAnchorTags.push(nextNode); 
     } 
     else nextNode = null; 
    } 
    while(nextNode); 
} 
//All the nodes that follow your required text is in myAnchorTags array. 
+0

ohh did not знал, что я могу использовать XPAtH с js. Нет, первый пример вернет более 80 элементов, как их отличить? Второй вернул бы мой первый «а», верно? Тогда я могу получить другие с .nexSibling и так далее. Но как я могу получить текст Sequel/Prequel? – Nemos

+0

Это может помочь вам начать с XPath в js http://www.w3schools.com/xpath/xpath_examples.asp. И немного изменил мой ответ (выделенный селектор Xpath и CSS) для большей ясности. –

+0

Спасибо, и я добавила в редакцию мой комментарий :) Я все еще нажимаю Enter, когда хочу сделать абзац:/ – Nemos

0

Мое мнение по этому вопросу будет:

var content = document.getElementById("content"); 
var h2 = content.getElementsByTagName("h2")[0]; // the first h2 element 
var link1 = h2.nextElementSibling; 
var link2 = link1.nextElementSibling; 
var link3 = link2.nextElementSibling; 
var link4 = link3.nextElementSibling; 
console.log("Sequel: ", link1.innerHTML, link1.href); 
console.log("Sequel: ", link2.innerHTML, link2.href); 
console.log("Sequel: ", link3.innerHTML, link3.href); 
console.log("Prequel: ", link4.innerHTML, link4.href); 

Этот метод имеет преимущество работы даже при наличии ссылки внутри первого (раздели) table.

Но это не будет работать, если первые (раздел) table содержит h2 элементов ... В этом случае, вместо

var h2 = content.getElementsByTagName("h2")[0]; // the first h2 element 

Вы должны использовать

var h2 = Array.prototype.filter.call(content.children, function(c) {return c.tagName.toLowerCase() == "h2"})[0]; 

EDIT
function listlinks(){ 
var prequels = []; 
var sequels = []; 
var all_h2_elems = document.getElementsByTagName("h2"); 
var h2_start = Array.prototype.filter.call(all_h2_elems, function(el){return el.innerText.indexOf("Related") != -1})[0]; 
var parent = h2_start.parentElement; 
var h2_elems = Array.prototype.filter.call(parent.children, function(c) {return c.tagName.toLowerCase() == "h2"}); 
if (h2_elems.length < 2) console.log("You lied, you said there were always 2 h2 tags!"); 
if (!h2_start.isSameNode(h2_elems[0])) console.log("Hmmm, there should not be a h2 tag before the 'Related' one, fix your question."); 
var sequel = false; 
var prequel = false; 
var current = h2_elems[0]; 
var end = h2_elems[1] 
while(current && !current.isSameNode(end)) 
{ 
    if (current.tagName === undefined) 
    { 
    if (current.nodeValue.indexOf("Sequel") != -1) 
    { 
     if (sequel || prequel) { console.log("wtf? another sequel?"); break; } 
     sequel = true; 
    } 
    else if (current.nodeValue.indexOf("Prequel") != -1) 
    { 
     if (!sequel) { console.log("wtf? prequel should be AFTER sequel"); break; } 
     prequel = true; 
     sequel = false; 
    } 
    else if (current.nodeValue.match(/[a-z]/)){ 
     prequel = false; 
     sequel = false; 
     // stop outputing links if anything else is found 
    } 
    } // end if (current.tagName === undefined) 
    else if (current.tagName.toLowerCase() === "a") 
    { 
    if (prequel) prequels.push(current.innerHTML + " : " + current.href); 
    if (sequel) sequels.push(current.innerHTML + " : " + current.href); 
    } 
    current = current.nextSibling; 
} 
    return [prequels,sequels]; 
} 
listlinks().forEach(function(el,i){console.log(i?"Sequels:":"Prequels:",el)}) 
+0

Спасибо, но я не знаю, сколько Элементов, которые мне нужны, будут в HTML. Таким образом, статический путь, вероятно, не работает. Я редактировал свой стартовый пост. – Nemos

+0

Там вы идете. Все ссылки, независимо от того, что на странице выводится в консоли. – Camusensei

+0

Nevermind, я не видел изменения разметки -_- «Я исправлю это – Camusensei

Смежные вопросы