парсинг данных с помощью BeautifulSoup

Парсинг данных с помощью BeautifulSoup

Привет всем! Сегодняшняя запись посвящена интересной теме, которая звучит как «Парсинг данных с помощью BeautifulSoup». Зачем все это? Решать вам, в любом случае — я не агитирую нарушать закон (например, собирая личные данные), а лишь показываю, что получать данные можно более удобным методом, чем просто просматривая те или иные сайты. Поехали!

Легкое отступление: в Python имеются три основные библиотеки, которые служат для получения данных с сайтов: BeautifulSoup, Scrapy и Selenium.

BeautifulSoup работает с помощью дополнения requests — которые организовывают html-запросы к нужным сайтам, а уж полученный ответ мы обрабатываем с помощью BeautifulSoup.

Учитывая, что мы сегодня будем рассматривать BeautifulSoup (некоторые примеры практического использования библиотеки я описывал ранее) — к двум другим библиотекам вернемся позднее 🙂

Итак, вначале нам нужно установить библиотеку. Для этого устанавливаем requests:

pip3 install beautifulsoup4 requests

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

import requests
headers = requests.utils.default_headers()
headers.update({ 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/69.0'})

Итак, заголовок (поддельный) браузера мы установили, и для проверки — поверит ли сайт тому, что мы действительно те, за кого себя выдаем — зайдем на какой-то сайт:

from bs4 import BeautifulSoup
url = "https://google.com"
req = requests.get(url, headers)
soup = BeautifulSoup(req.content, 'html.parser')
print(soup.prettify())

Теперь создаем объект BeautifulSoup, который нужен для приема необработанных данных, полученных через req.content. Второй параметр — html.parser — это способ сообщить нашей библиотеке BeautifulSoup о том, что это — html — документ. После того, как объект создан — мы можем для начала посмотреть, как выглядит наша переменная soup с помощью print (soup.prettify ()):

<!DOCTYPE doctype html>
<html itemscope="" itemtype="http://schema.org/WebPage" lang="de"><head><meta content="text/html; charset=utf-8" http-equiv="Content-Type"/><meta content="/images/branding/googleg/1x/googleg_standard_color_128dp.png" itemprop="image"/><title>Google</title><script nonce="178M9oBjYXZ8yIDMu0h7uw==">(function(){window.google={kEI:'Xlf2XYW_Ca2XmwWm37qYDA',kEXPI:'0,1353747,5662,730,224,1418,3309,377,207,467,2487,250,10,169,544,338,175,364,671,483,3,205,73,4,60,315,635,10,400,1129068,143,1197764,385,26,329092,1294,12383,4855,32691,15248,867,28684,364,3319,5505,8384,1119,2,578,728,2431,1362,3471,852,4968,773,2248,4746,7,3113,6194,1719,1808,1976,2044,8909,5297,2972,875,38,1179,2975,2736,1558,2136,7432,3874,2883,21,317,235,3913,1,369,1398,1379,520,399,992,1285,8,2796,967,601,11,14,1279,2212,202,37,291,149,1103,840,324,193,317,1149,4,4,48,158,662,3438,260,52,1137,2,2063,606,1839,184,595,1702,1947,244,503,429,44,1009,93,328,1284,16,84,417,2426,1639,608,473,1339,748,1039,3094,133,773,1548,524,7,728,89,503,1574,3194,99,101,1345,3,6510,2244,588,257,215,367,111,120,128,681,1042,2459,1617,1067,4,842,3093,1274,108,1246,2,2,22,1001,565,88,481,809,99,2,433,1223,255,118,6,5,1515,128,757,989,258,265,326,35,1154,10,275,2,62,87,585,458,302,1707,9,46,45,316,63,1158,828,841,66,1,109,10,2,16,146,138,333,109,373,959,487,10,26,201,29,156,625,189,6,15,276,234,39,40,255,6,252,7,450,28,3,4,664,751,95,17,307,471,863,5859138,1805893,4194851,2801171,549,333,444,1,2,80,1,900,896,1,8,1,2,2551,1,748,141,59,736,563,1,4265,1,1,1,1,137,1,576,2,18,2,55,141,8,10,9,48,1,9,8,1,14,7,3,3,4,5,3,3,3,3,3,1,3,3,3,3,25,22,52,9,4,2,2,13,2,2,2,2,23964507',authuser:0,kscs:'c9c918f0_Xlf2XYW_Ca2XmwWm37qYDA',kGL:'DE',kBL:'9hVE'};google.sn='webhp';google.kHL='de';google.jsfs='Ffpdje';})();(function(){google.lc=[];google.li=0;google.getEI=function(a){for(var b;a&&(!a.getAttribute||!(b=a.getAttribute("eid")));)a=a.parentNode;return b||google.kEI};google.getLEI=function(a){for(var b=null;a&&(!a.getAttribute||!(b=a.getAttribute("leid")));)a=a.parentNode;return b};google.https=function(){return"https:"==window.location.protocol};google.ml=function(){return null};google.time=function(){return(new Date).getTime()};google.log=function(a,b,e,c,g){if(a=google.logUrl(a,b,e,c,g)){b=new Image;var d=google.lc,f=google.li;d[f]=b;b.onerror=b.onload=b.onabort=function(){delete d[f]};google.vel&&google.vel.lu&&google.vel.lu(a);b.src=a;google.li=f+1}};google.logUrl=function(a,b,e,c,g){var d="",f=google.ls||"";e||-1!=b.search("&ei=")||(d="&ei="+google.getEI(c),-1==b.search("&lei=")&&(c=google.getLEI(c))&&(d+="&lei="+c));c="";!e&&google.cshid&&-1==b.search("&cshid=")&&"slh"!=a&&(c="&cshid="+google.cshid);a=e||"/"+(g||"gen_204")+"?atyp=i&ct="+a+"&cad="+b+d+f+"&zx="+google.time()+c;/^http:/i.test(a)&&google.https()&&(google.ml(Error("a"),!1,{src:a,glmm:1}),a="");return a};}).call(this);(function(){google.y={};google.x=function(a,b){if(a)var c=a.id;else{do c=Math.random();while(google.y[c])}google.y[c]=[a,b];return!1};google.lm=[];google.plm=function(a){google.lm.push.apply(google.lm,a)};google.lq=[];google.load=function(a,b,c){google.lq.push([[a],b,c])};google.loadAll=function(a,b){google.lq.push([a,b])};}).call(this);google.f={};(function(){document.documentElement.addEventListener("submit",function(b){var a;if(a=b.target){var c=a.getAttribute("data-submitfalse");a="1"==c||"q"==c&&!a.elements.q.value?!0:!1}else a=!1;a&&(b.preventDefault(),b.stopPropagation())},!0);}).call(this);var a=window.location,b=a.href.indexOf("#");if(0<=b){var c=a.href.substring(b+1);/(^|&)q=/.test(c)&&-1==c.indexOf("#")&&a.replace("/search?"+c.replace(/(^|&)fp=[^&]*/g,"")+"&cad=h")};</script><style>#gbar,#guser{font-size:13px;padding-top:1px !important;}#gbar{height:22px}#guser{padding-bottom:7px !important;text-align:right}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}@media all{.gb1{height:22px;margin-right:.5em;vertical-align:top}#gbar{float:left}}a.gb1,a.gb4{text-decoration:underline !important}a.gb1,a.gb4{color:#00c !important}.gbi .gb4{color:#dd8e27 !important}.gbf .gb4{color:#900 !important}
</style><style>body,td,a,p,.h{font-family:arial,sans-serif}body{margin:0;overflow-y:scroll}#gog{padding:3px 8px 0}td{line-height:.8em}.gac_m td{line-height:17px}form{margin-bottom:20px}.h{color:#36c}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}em{font-weight:bold;font-style:normal}.lst{height:25px;width:496px}.gsfi,.lst{font:18px arial,sans-serif}.gsfs{font:17px arial,sans-serif}.ds{display:inline-box;display:inline-block;margin:3px 0 4px;margin-left:4px}input{font-family:inherit}a.gb1,a.gb2,a.gb3,a.gb4{color:#11c !important}body{background:#fff;color:black}a{color:#11c;text-decoration:none}a:hover,a:active{text-decoration:underline}.fl a{color:#36c}a:visited{color:#551a8b}a.gb1,a.gb4{text-decoration:underline}a.gb3:hover{text-decoration:none}#ghead a.gb2:hover{color:#fff !important}.sblc{padding-top:5px}.sblc a{display:block;margin:2px 0;margin-left:13px;font-size:11px}.lsbb{background:#eee;border:solid 1px;border-color:#ccc #999 #999 #ccc;height:30px}.lsbb{display:block}.ftl,#fll a{display:inline-block;margin:0 12px}.lsb{background:url(/images/nav_logo229.png) 0 -261px repeat-x;border:none;color:#000;cursor:pointer;height:30px;margin:0;outline:0;font:15px arial,sans-serif;vertical-align:top}.lsb:active{background:#ccc}.lst:focus{outline:none}</style><script nonce="178M9oBjYXZ8yIDMu0h7uw=="></script></head><body bgcolor="#fff"><script nonce="178M9oBjYXZ8yIDMu0h7uw==">(function(){var src='/images/nav_logo229.png';var iesg=false;document.body.onload = function(){window.n && window.n();if (document.images){new Image().src=src;}
if (!iesg){document.f&&document.f.q.focus();document.gbqf&&document.gbqf.q.focus();}
}
})();</script><div id="mngb"> <div id="gbar"><nobr><b class="gb1">Suche</b> <a class="gb1" href="https://www.google.de/imghp?hl=de&amp;tab=wi">Bilder</a> <a class="gb1" href="https://maps.google.de/maps?hl=de&amp;tab=wl">Maps</a> <a class="gb1" href="https://play.google.com/?hl=de&amp;tab=w8">Play</a> <a class="gb1" href="https://www.youtube.com/?gl=DE&amp;tab=w1">YouTube</a> <a class="gb1" href="https://news.google.de/nwshp?hl=de&amp;tab=wn">News</a> <a class="gb1" href="https://mail.google.com/mail/?tab=wm">Gmail</a> <a class="gb1" href="https://drive.google.com/?tab=wo">Drive</a> <a class="gb1" href="https://www.google.de/intl/de/about/products?tab=wh" style="text-decoration:none"><u>Mehr</u> »</a></nobr></div><div id="guser" width="100%"><nobr><span class="gbi" id="gbn"></span><span class="gbf" id="gbf"></span><span id="gbe"></span><a class="gb4" href="http://www.google.de/history/optout?hl=de">Webprotokoll</a> | <a class="gb4" href="/preferences?hl=de">Einstellungen</a> | <a class="gb4" href="https://accounts.google.com/ServiceLogin?hl=de&amp;passive=true&amp;continue=https://www.google.com/%3FUser-Agent%3DMozilla%252F5.0%2B%2528X11%253B%2BUbuntu%253B%2BLinux%2Bx86_64%253B%2Brv%253A52.0%2529%2BGecko%252F20100101%2BFirefox%252F69.0%26Accept-Encoding%3Dgzip%252C%2Bdeflate%26Accept%3D%252A%252F%252A%26Connection%3Dkeep-alive" id="gb_70" target="_top" rel="noopener noreferrer">Anmelden</a></nobr></div><div class="gbh" style="left:0"></div><div class="gbh" style="right:0"></div> </div><center><br clear="all" id="lgpd"/><div id="lga"><img alt="Google" height="92" id="hplogo" src="/images/branding/googlelogo/1x/googlelogo_white_background_color_272x92dp.png" style="padding:28px 0 14px" width="272"/><br/><br/></div><form action="/search" name="f"><table cellpadding="0" cellspacing="0"><tr valign="top"><td width="25%"> </td><td align="center" nowrap=""><input name="ie" type="hidden" value="ISO-8859-1"/><input name="hl" type="hidden" value="de"/><input name="source" type="hidden" value="hp"/><input name="biw" type="hidden"/><input name="bih" type="hidden"/><div class="ds" style="height:32px;margin:4px 0"><input autocomplete="off" class="lst" maxlength="2048" name="q" size="57" style="color:#000;margin:0;padding:5px 8px 0 6px;vertical-align:top" title="Google-Suche" value=""/></div><br style="line-height:0"/><span class="ds"><span class="lsbb"><input class="lsb" name="btnG" type="submit" value="Google-Suche"/></span></span><span class="ds"><span class="lsbb"><input class="lsb" id="tsuid1" name="btnI" type="submit" value="Auf gut Glück!"/><script nonce="178M9oBjYXZ8yIDMu0h7uw==">(function(){var id='tsuid1';document.getElementById(id).onclick = function(){if (this.form.q.value){this.checked = 1;if (this.form.iflsig)this.form.iflsig.disabled = false;}
else top.location='/doodles/';};})();</script><input name="iflsig" type="hidden" value="AAP1E1EAAAAAXfZlbq6q7NUfWY2axRbPFfACMU2Cjn9M"/></span></span></td><td align="left" class="fl sblc" nowrap="" width="25%"><a href="/advanced_search?hl=de&amp;authuser=0">Erweiterte Suche</a><a href="/language_tools?hl=de&amp;authuser=0">Sprachoptionen</a></td></tr></table><input id="gbv" name="gbv" type="hidden" value="1"/><script nonce="178M9oBjYXZ8yIDMu0h7uw==">(function(){var a,b="1";if(document&&document.getElementById)if("undefined"!=typeof XMLHttpRequest)b="2";else if("undefined"!=typeof ActiveXObject){var c,d,e=["MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"];for(c=0;d=e[c++];)try{new ActiveXObject(d),b="2"}catch(h){}}a=b;if("2"==a&&-1==location.search.indexOf("&gbv=2")){var f=google.gbvu,g=document.getElementById("gbv");g&&(g.value=a);f&&window.setTimeout(function(){location.href=f},0)};}).call(this);</script></form><div id="gac_scont"></div><div style="font-size:83%;min-height:3.5em"><br/></div><span id="footer"><div style="font-size:10pt"><div id="fll" style="margin:19px auto;text-align:center"><a href="/intl/de/ads/">Werben mit Google</a><a href="/services/">Unternehmensangebote</a><a href="/intl/de/about.html">Über Google</a><a href="https://www.google.com/setprefdomain?prefdom=DE&amp;prev=https://www.google.de/&amp;sig=K_TJIKKXkIcrvEdDSbUcjja7A3tJE%3D">Google.de</a></div></div><p style="color:#767676;font-size:8pt">© 2019 - <a href="/intl/de/policies/privacy/">Datenschutzerklärung</a> - <a href="/intl/de/policies/terms/">Nutzungsbedingungen</a></p></span></center><script nonce="178M9oBjYXZ8yIDMu0h7uw==">(function(){window.google.cdo={height:0,width:0};(function(){var a=window.innerWidth,b=window.innerHeight;if(!a||!b){var c=window.document,d="CSS1Compat"==c.compatMode?c.documentElement:c.body;a=d.clientWidth;b=d.clientHeight}a&&b&&(a!=google.cdo.width||b!=google.cdo.height)&&google.log("","","/client_204?&atyp=i&biw="+a+"&bih="+b+"&ei="+google.kEI);}).call(this);})();(function(){var u='/xjs/_/js/k\x3dxjs.hp.en.3mkxARIkkN0.O/m\x3dsb_he,d/am\x3dAAMCbAQ/d\x3d1/rs\x3dACT90oH0ZgFCL-q_Qh6y8ytgGBhQJ9zvUw';
setTimeout(function(){var b=document;var a="SCRIPT";"application/xhtml+xml"===b.contentType&&(a=a.toLowerCase());a=b.createElement(a);a.src=u;google.timers&&google.timers.load&&google.tick&&google.tick("load","xjsls");document.body.appendChild(a)},0);})();(function(){window.google.xjsu='/xjs/_/js/k\x3dxjs.hp.en.3mkxARIkkN0.O/m\x3dsb_he,d/am\x3dAAMCbAQ/d\x3d1/rs\x3dACT90oH0ZgFCL-q_Qh6y8ytgGBhQJ9zvUw';})();function _DumpException(e){throw e;}
function _F_installCss(c){}
(function(){google.spjs=false;google.snet=true;google.em=[];google.emw=false;})();(function(){var pmc='{\x22d\x22:{},\x22sb_he\x22:{\x22agen\x22:true,\x22cgen\x22:true,\x22client\x22:\x22heirloom-hp\x22,\x22dh\x22:true,\x22dhqt\x22:true,\x22ds\x22:\x22\x22,\x22ffql\x22:\x22de\x22,\x22fl\x22:true,\x22host\x22:\x22google.com\x22,\x22isbh\x22:28,\x22jsonp\x22:true,\x22lm\x22:true,\x22msgs\x22:{\x22cibl\x22:\x22Suche löschen\x22,\x22dym\x22:\x22Meintest du:\x22,\x22lcky\x22:\x22Auf gut Glück!\x22,\x22lml\x22:\x22Weitere Informationen\x22,\x22oskt\x22:\x22Eingabetools\x22,\x22psrc\x22:\x22Diese Suchanfrage wurde aus deinem \\u003Ca href\x3d\\\x22/history\\\x22\\u003EWebprotokoll\\u003C/a\\u003E entfernt.\x22,\x22psrl\x22:\x22Entfernen\x22,\x22sbit\x22:\x22Bildersuche\x22,\x22srch\x22:\x22Google-Suche\x22},\x22ovr\x22:{},\x22pq\x22:\x22\x22,\x22refpd\x22:true,\x22rfs\x22:[],\x22sbpl\x22:24,\x22sbpr\x22:24,\x22scd\x22:10,\x22sce\x22:5,\x22stok\x22:\x22xnireY0bsuzaeIe34r_TdLefuGI\x22,\x22uhde\x22:false}}';google.pmc=JSON.parse(pmc);})();</script> </body></html>

Выглядит, конечно, круто и внушительно, но как получить из всего этого внятные данные? Для начала давайте определимся с тем, что получение данных с сайтов так или иначе связано с тегами — т.е. нам нужно разобраться, как их (теги) распознавать, и как получать информацию, находящуюся внутри тегов.

Начнем с простого — использование soup.find(…) или soup.find_all(…). Разница между командами заключается в том, что первый вариант найдет только один нужный нам тег (самый первый), в то время, как второй вариант покажет все варианты расположения нужного тега.

Давайте попробуем найти в каше, полученной выше — все ссылки с тегом a href.

variable = soup.find_all('a') #получаем вообще все, что связано с тегом a href
for tag in variable: #и теперь по этому списку идем, выгребая конкретно ссылки
print(tag.get('href'))

Полный код, созданным нами за сегодня, благодаря чему мы подделываем заголовок, получаем содержимое целевой страницы, и выгребаем все ссылки выглядит так:

import requests
from bs4 import BeautifulSoup
headers = requests.utils.default_headers()
headers.update({ 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/69.0'})
url = "https://www.google.com/"
req = requests.get(url, headers)
soup = BeautifulSoup(req.content, 'html.parser')
variable = soup.find_all('a')
for tag in variable:
print(tag.get('href'))

Для начала хватит 🙂 Сегодня мы научились подключать библиотеку BeautifulSoup, подделывать заголовок браузера для запроса, и с помощью библиотеки BeautifulSoup получать список нужных нам тегов. Да, всего 11 строчек 🙂

Скоро продолжение 🙂 Спасибо за внимание!