Не могу спарсить все название песен из блока div
Начинал изучать Scrapy, и всё было хорошо пока я не столкнулся с этой проблемой:
Я создал цикл где я начал перебирать все названия и ссылок песен в блоке div. Ссылок Scrapy спарсил хорошо, но название песен он не смог корректно обработать. Он спарсил название только первой музыки, а остальных не трогал.
Вот код:
import scrapy
class ParserSpider(scrapy.Spider):
name = 'parser'
allowed_domains = ['downloadmusicvk.ru']
start_urls = ['https://downloadmusicvk.ru/audio/search?q=all']
def parse(self, response):
for el in response.css('#w1 > div'):
title = el.xpath('//div/div[1]/span/following::text()').get()
link = el.css('div.row.audio.vcenter > div.col-lg-9.col-md-8.col-sm-6.col-xs-5 > span > b > a::attr(href)').get()
yield {
'link': link,
'title': title
}
Вот сам сайт где я парсил все эти данные: https://downloadmusicvk.ru/audio/search?q=all
Пример сайта:
Это ошибка или я что-то упустил?
Когда я написал:
title = el.xpath('//div/div[1]/span/following::text()').getall()
print(title)
Он вернул мне вот этот массив:
[' - All the Time ', '\n', '\n\n 3:39', '\n', '\n', '\n', '\n',
'\n\n\n\n', ' ', '\n', '\n', '\n', '\n\n\n\n', 'Mishlawi', ' - All Night ',
'\n', '\n\n 2:54', '\n', '\n', '\n', '\n', '\n\n\n\n', ' ', '\n', '\n',
'\n', '\n\n\n\n', 'Miyagi & Andy Panda', ' - All the Time ', '\n', '\n\n
3:39', '\n', '\n', '\n', '\n', '\n\n\n\n', ' ', '\n', '\n',
'\n\n\n\n\n\n\n', '\n', '\n\n\n\n', 'Lil Peep', ' - Broken Smile (My All) ',
'\n', '\n\n 4:40', '\n', '\n', '\n', '\n', '\n\n\n\n', ' ', '\n', '\n',
'\n', '\n\n\n\n', 'Billie Eilish', ' - all the good girls go to hell ',
'\n', '\n\n 2:48', '\n', '\n', '\n', '\n', '\n\n\n\n', ' ', '\n', '\n',
'\n', '\n\n\n\n', 'mishlawi', ' - all night ', '\n', '\n\n 3:18', '\n',
'\n', '\n', '\n', '\n\n\n\n', ' ', '\n', '\n', '\n', '\n\n\n\n',
'MORGENSHTERN', " - Fuck 'Em All ", '\n', '\n\n 2:23', '\n', '\n', '\n',
'\n', '\n\n\n\n', ' ', '\n', '\n', ' ', '\n', '\n', '\n', '\n', '\n',
'\n\n\n\n', 'Real1', ' - All The Way Up (Black Lion Entertainment Records
Remix) ', '\n', '\n\n 3:11', '\n', '\n', '\n', '\n', '\n\n\n\n', ' ', '\n',
'\n', '\n', '\n', '\n\n\n\n', 'Jah Khalib', ' - All About You ', '\n',
'\n\n 3:18', '\n', '\n', '\n', '\n', '\n\n\n\n', ' ', '\n', '\n', '\n',
'\n\n\n\n', 'RØNIN', ' - ALL GIRLS ARE THE SAME ', '\n', '\n\n 2:02', '\n',
'\n', '\n', '\n', '\n\n\n\n', ' ', '\n', '\n', '«', '\n', '1', '\n', '2',
'\n', '3', '\n', '4', '\n', '5', '\n', '»', ' ', '\n', '\n', 'Поделись',
'\n', '\n', '\n', '\n', '\n \n\n\n', '\n', '\n\n\n\n', '\n', '\n', '\n',
'\n', '\n', '\n', 'Наверх', '\n', '© 2021 DownloadMusicVK · ', 'Правила', '
· ', 'Скачать\nвидео с ВК', ' · ', 'Реклама', ' · ', 'Телеграм', '\n',
'\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
'\n', 'jQuery(function ($) {\njQuery&&jQuery.pjax&&
(jQuery.pjax.defaults.maxCacheLength=0);\nvar w0_data_1 = new
Bloodhound({"datumTokenizer":Bloodhound.tokenizers.whitespace,"queryTokenize
r":Bloodhound.tokenizers.whitespace,"remote":{"url":"/audio/hints?
q=%QUERY","wildcard":"%QUERY"}});\nkvInitTA(\'w0\', typeahead_307a21f9,
[{"name":"w0_data_1","source":w0_data_1.ttAdapter()}]);\nvar w3_data_1 = new
Bloodhound({"datumTokenizer":Bloodhound.tokenizers.whitespace,"queryTokenizer":Bloodhound.tokenizers.whitespace,"remote":
{"url":"https://downloadmusicvk.ru/audio/hints?
q=%QUERY","wildcard":"%QUERY"}});\nkvInitTA(\'w3\', typeahead_307a21f9,
[{"name":"w3_data_1","source":w3_data_1.ttAdapter()}]);\n});', ' ', '\n',
'\n', '\n', '\n', '×', '\n', 'Что-то блокирует рекламу!', '\n', '\n', '\n',
'Чтобы скачать музыку с ВК, выключите пожалуйста расширение блокирующее
рекламу или внесите\nэтот сайт в список исключений, или попробуйте зайти с
другого браузера.', '\n', 'Расширения обычно находятся сверху справа в
браузере или в разделе Дополнительные инструменты\n-> Расширения.', '\n',
'На нашем сайте нет назойливой рекламы и сайт существует на доходы с нее,
чтобы вы могли\nкачать музыку с ВК бесплатно.', '\n', '\n ', 'Как отключить
блокировку рекламы?', '\n', '\n', '\n', '\n', '\n', '\n', "\n
let tnSubscribeOptions = {\n serviceWorkerRelativePath:
'/tnServiceWorker.js',\n block: '881504'\n };\n
", '\n', '\n', '\n (function () {\n var sc =
document.createElement("script");\n var stime = 0;\n
try {\n stime = new Event("").timeStamp.toFixed(2);\n } catch (e) {\n
}\n sc.type = "text/javascript";\n
sc.setAttribute("data-mrmn-tag", "iam");\n
sc.setAttribute("async", "async");\n sc.src =
"https://pdvacde.com/wcm/?"\n + "sh=" +
document.location.host.replace(/^www\\./, "")\n +
"&sth=e2df249aef11088abf1542a800217192"\n +
"&m=755dfe5b31411c7fafd9ea25f3ec44ba"\n + "&sid=" +
parseInt(Math.random() * 1e3) + "_" + parseInt(Math.random() * 1e6) + "_" +
parseInt(Math.random() * 1e9)\n + "&stime=" + stime\n
+ "&rand=" + Math.random();\n if
(document.head) {\n document.head.appendChild(sc);\n
} else {\n var node =
document.getElementsByTagName("script")[0];\n
node.parentNode.insertBefore(sc, node);\n }\n })
();\n ', '\n', '\n']
el.xpath().getall() каким то образом берет все блоки из класса w1. Типа в этой функции он работает вот так:
HTML:
<div class='w1'>
<div><a>1<a></div>
<div><a>2<a></div>
<div><a>3<a></div>
<div><a>4<a></div>
</div>
Python:
for el in response.xpath('//*[@id="w1"]/div'):
print(el.xpath('a::text()'))
И на выход он дает все элементы повторяя 4 раза:
1
2
3
4
1
2
3
4
1
2
3
4
1
2
3
4
А el.xpath().get() вот так:
1
1
1
1
Ответы (2 шт):
def parse(self, response):
titles = [x.strip() for x in response.xpath("//div[@class='list-view']//div[contains(@class, 'row')]/div[1]/text()").getall() if x.strip()]
links = response.xpath("//div[@class='list-view']//div[contains(@class, 'row')]/div[1]/span/b/a/text()").getall()
for i, title in enumerate(titles):
link = links[i]
yield {'link': link, 'title': title}
Вот так мне кажется проще будет.
Либо добавить точку в начало пути xpath, чтобы поиск стал относительным.
def parse(self, response):
for el in response.css('#w1 > div'):
title = el.xpath('.//div/div[1]/span/following::text()').get()
link = el.css('div.row.audio.vcenter > div.col-lg-9.col-md-8.col-sm-6.col-xs-5 > span > b > a::attr(href)').get()
yield {
'link': link,
'title': title
}


