2016-11-09 3 views
0

Я пытаюсь очистить сайт, но результаты, возвращенные только для ссылок, отличаются от того, когда я проверяю его с помощью браузера.Результаты Nokogiri отличаются от проверки броузера

В моем браузере я получаю обычные ссылки, но все ссылки HREF становятся javascript:void(0); от Nokogiri.

Вот сайт:

https://www.ctgoodjobs.hk/jobs/part-time 

Вот мой код:

url = "https://www.ctgoodjobs.hk/jobs/part-time" 
response = open(url) rescue nil 
next unless response 
doc = Nokogiri::HTML(open(url)) 
links = doc.search('.job-title > a').text 
+0

Пожалуйста, прочтите «[mcve]». Когда вы спрашиваете о коде, который вы написали, мы ожидаем минимальный код и минимальные входные данные в вопросе, который демонстрирует проблему. Не делая этого заставляет нас работать из огромных HTML-файлов и разделять их на полезные и важные части, теряя время, замедляя нашу способность помочь вам и потенциально отвлекаться от реальной проблемы. –

ответ

1

не так просто, URL'ы, являются «затемняется», используя функцию JS, поэтому вы получаете javascript: void(0) при запросе hrefs ... глядя на html, есть некоторые скрытые входы для каждой ссылки, и есть URL-адрес предварительного просмотра, который вы можете использовать для создания URL-адреса предварительного просмотра задания (если это то, что вы ищете), поэтому у вас есть следующее:

<div class="result-list-job current-view"> 
    <input type="hidden" name="job_id" value="04375145"> 
    <input type="hidden" name="each_job_title_url" value="barista-senior-barista-咖啡調配員"> 
    <h2 class="job-title"><a href="javascript:void(0);">Barista/ Senior Barista 咖 啡 調 配 員</a></h2> 
    <h3 class="job-company"><a href="/company-jobs/pacific-coffee-company/00028652" target="_blank">PACIFIC COFFEE CO. LTD.</a></h3> 
    <div class="job-description"> 
    <ul class="job-desc-list clearfix"> 
     <li class="job-desc-loc job-desc-small-icon">-</li> 
     <li class="job-desc-work-exp">0-1 yr(s)</li> 
     <li class="job-desc-salary job-desc-small-icon">-</li> 
     <li class="job-desc-post-date">09/11/16</li> 
    </ul> 
    </div> 
    <a class="job-save-btn" title="save this job" style="display: inline;"> </a> 
    <div class="job-batch-apply"><span class="checkbox" style="background-position: 0px 0px;"></span><input type="checkbox" class="styled" name="job_checkbox" value="04375145"></div> 
    <div class="job-cat job-cat-de"></div> 
</div> 

тогда, вы можете получить каждый job_id из этих входов, как:

inputs = doc.search('//input[@name="job_id"]') 

, а затем построить URLs (я нашел базовый URL в joblist_preview.js:

urls = inputs.map do |input| 
    "https://www.ctgoodjobs.hk/english/jobdetails/details.asp?m_jobid=#{input['value']}&joblistmode=previewlist&ga_channel=ct" 
end 
0

Возьмите выходной браузером и инструментом такого типа, как wget, curl или nokogiri, и вы найдете HTML-браузер, который может отличаться от исходного HTML-кода.

Браузеры в эти дни могут обрабатывать DHTML, Nokogiri этого не делает. Вы можете получить только текст, используя что-то, что позволяет просматривать контент без браузера, например, вышеупомянутые инструменты, а затем сравнить его с тем, что вы видите в текстовом редакторе, или то, что показывает nokogiri. Не доверяйте браузеру - они, как известно, лгут, потому что хотят сделать вас счастливыми.

Вот быстрый взгляд на то, что исходный HTML содержит, генерируется с помощью:

$ nokogiri "https://www.ctgoodjobs.hk/jobs/part-time" 

Nokogiri высадил меня в IRB:

Your document is stored in @doc... 
Welcome to NOKOGIRI. You are using ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin15]. Have fun ;) 

Counting хиты, найденного возвращается селекторных:

>> @doc.search('.job-title > a').size 
30 

Просмотреть результаты поиска:

>> @doc.search('.job-title > a').map(&:text) 
[ 
    [ 0] "嬰 兒 奶 粉 沖 調 機 - 兼 職 產 品 推 廣 員 Part Time Promoter (時 薪 高 達 HK$90, 另 設 銷 售 佣 金)", 
... 
    [29] "Customer Services Representative (Part-time)" 
] 

Глядя на фактическое href:

>> @doc.search('.job-title > a').map{ |n| n['href'] } 
[ 
    [ 0] "javascript:void(0);", 
... 
    [29] "javascript:void(0);" 
] 

Вы можете сказать HTML не содержит ничего, кроме того, что Nokogiri говорит вам, так что браузер после обработки HTML, DHTML обработки и изменение страницы, которую вы видите, если вы используете что-то, чтобы посмотреть на HTML. Итак, короткое исправление, не доверяйте браузеру, если вы хотите знать, что сервер отправляет вам.

Вот почему скребок не очень надежный, и вы должны использовать API, если это вообще возможно.Если вы не можете, тогда вам придется сворачивать рукава и копаться в JavaScript и вручную интерпретировать, что он делает, а затем извлекать данные и анализировать их во что-то полезное.

Ваш код может быть очищен и упрощен. Я пишу это гораздо проще, как:

url = "https://www.ctgoodjobs.hk/jobs/part-time" 
doc = Nokogiri::HTML(open(url)) 
links = doc.search('.job-title > a').map(&:text) 

Использование search(...).text является большой ошибкой. text, применяемый к NodeSet, объединяет текст каждого содержащегося узла, что чрезвычайно затрудняет получение отдельного текста. Рассмотрим это:

require 'nokogiri' 
doc = Nokogiri::HTML(<<EOT) 
<html> 
    <body> 
    <p>foo</p> 
    <p>bar</p> 
    </body> 
</html> 
EOT 

doc.search('p').class # => Nokogiri::XML::NodeSet 

doc.search('p').text # => "foobar" 
doc.search('p').map(&:text) # => ["foo", "bar"] 

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

Вместо этого используйте map для повторения элементов и применения &:text к каждому, возвращая массив текста каждого элемента.

См. Также "How to avoid joining all text from Nodes when scraping" и "Taking apart a DHTML page".

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