Получите результаты поиска Google через Powershell
Допустим, у вас есть только артист и название из музыкального файла, но вы не знаете название альбома.
Когда вы делаете поиск Google в Chrome для т.е. Golden Earring Radar Love Album
ты получаешь:
Вы видите название альбома (Moontan), дату выпуска (июль 1973 года) и даже правильную обложку альбома. Как называется этот раздел страницы? Google Preview? Google Instant Page? Я не знаю
Мой вопрос
Как программно получить эту информацию через PowerShell?
Что я пробовал
Invoke-Webrequest: не работает, конкретный контент не отвечает
$Response = Invoke-WebRequest -URI "https://www.google.com/search?hl=en&q=Golden+Earring+Radar+Love+Album" $Response.content | Set-Content D:\test.txt
XmlHttpRequest: не работает, конкретный контент не отвечает
$objXmlHttp = New-Object -ComObject MSXML2.ServerXMLHTTP $objXmlHttp.Open("GET", "https://www.google.com/search?hl=en&q=Golden+Earring+Radar+Love+Album") $objXmlHttp.Send() $objXmlHttp.responseText | Set-Content D:\test.txt
Invoke-RestMethod: не работает, извлекает только URL и их фрагменты
$Response = Invoke-RestMethod -Uri 'https://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=Golden%20Earring%20Radar%20Love%20Album' $Response.responseData.results
Я искал Google Play или Google Music API, который можно использовать в PowerShell
Я считаю, что проблема в том, что эта информация загружается через Javascript, который не выполняется при использовании таких методов, как Invoke-WebRequest. Я могу ошибаться здесь.
Я вижу два решения: 1) Имитировать веб-браузер в PowerShell и загружать весь сайт в форму. Или 2) Используйте Fiddler, чтобы увидеть, когда и как эта дополнительная информация загружается. Я бы предпочел второе решение, но оба вне моего понимания.
Предыстория, чтобы избежать комментариев о том, что есть и другие услуги, такие как XYZ, которые лучше соответствуют вашим потребностям
У меня уже есть рабочие скрипты PowerShell, чтобы получить название альбома и дополнительную информацию только по данному исполнителю и названию трека для многочисленных сервисов, включая Amazon, Deezer, Discogs, EchoNest, iTunes, Last.fm, MusicBrainz, Napster, rdio и Spotify. Потому что все они предлагают простой в использовании API (кроме Amazon. Их реализация довольно сложна).
Я провел несколько тестов с ~3000 музыкальными файлами, указав только исполнителя и название трека, чтобы получить соответствующее название альбома. И когда я сравнил результаты с Google, я заметил, что ни один из вышеперечисленных сервисов не был настолько точным, как Google.
1 ответ
- открыть профиль PowerShell
ii $profile
- вставьте следующий фрагмент в профиль
Function search-google {
$query = 'https://www.google.com/search?q='
$args | % { $query = $query + "$_+" }
$url = $query.Substring(0, $query.Length - 1)
start "$url"
}
Set-Alias glg search-google
- перезапустить сеанс PowerShell
- из консоли просто запустите новую команду
glg hello world
- кавычки для строк не нужны
Вполне возможно, что Google возвращает разные результаты в зависимости от пользовательского агента, который делает запрос. Таким образом, в вашем случае вы не передаете пользовательский агент, поэтому Google предполагает, что это не браузер, и ограничивает объем возвращаемой информации (возможно, для облегчения анализа).
Итак, у вас есть несколько вариантов, два из них:
- Как предлагает @AlexanderObersht, используйте Fiddler, чтобы прослушать часть сетевого трафика и посмотреть, какие дополнительные заголовки предоставляются по умолчанию, и возиться с ними (каламбур), чтобы посмотреть, сможете ли вы заставить его работать.
- С
Invoke-RestMethod
или жеInvoke-WebRequest
вам нужно будет добавить-Headers
параметр - С XMLHttpRequest вам нужно будет добавить заголовки в соответствующие свойства.
- С
- Если вы не хотите иметь дело с деталями браузера, вы можете просто автоматизировать IE непосредственно из Powershell. У меня есть образец, показанный ниже.
-
$ie = New-Object -com InternetExplorer.Application -ErrorAction Stop
$ie.Visible = $true
$ie.Navigate("https://www.bing.com")
while($ie.Busy) { Start-Sleep -Milliseconds 1 }
$ie.Document.DoStuff()