PuppeteerSharp kütüphanesi, bir node.js kütüphanesi olan Puppeteer'ın .NET platformunda kullanılması için oluşturulmuş bir kütüphanedir.
Aşağıdaki yazımda PuppeteerSharp kütüphanesini ilgili detaylı olarak anlattığım yazıyı bulabilirsiniz.
PuppeteerSharp Kütüphanesi Nedir? Ne Amaçla Kullanılır?
Bu yazımda ise PuppeteerSharp kütüphanesini kullanarak .Net 5 alt yapısı ile Google araması yapacağız.
Projemizde aşağıdaki gibi 3 adet proje yer alacaktır.
- PuppeteerSharp.ConsoleApp: Konsol uygulamamızdır. Bütün metotları buradan çalıştıracağız.
- PuppeteerSharp.Methods: PuppeteerSharp metotlarını kullanarak kendi metotlarımızın bulunduğu projemizdir.
- PuppeteerSharp.Models: Metotlarımızdan gelen başarılı / başarısız sonuç nesnelerini döndürdüğümüz projemizdir.
- OpenChromium metodu ile Page türünden bir sayfa tanımlanır. Bu metot, using bloklarında olmalıdır. Page nesnesi, IDisposable olduğu için işi bittiğinde kaynakları serbest bırakacaktır.
public static async Task<Page> OpenChromiumPage() | |
{ | |
var browserFetcher = new BrowserFetcher(new BrowserFetcherOptions | |
{ | |
Path = "D:\\Chromium" //You can replace with custom path. | |
}); | |
var revision = await browserFetcher.DownloadAsync(BrowserFetcher.DefaultChromiumRevision); | |
var browser = await Puppeteer.LaunchAsync(new LaunchOptions | |
{ | |
Headless = true, | |
ExecutablePath = revision.ExecutablePath | |
}); | |
return await browser.NewPageAsync(); | |
} |
- GetVideoSearchVideoResultUrlList: Aranacak kelime ile Google araması ve video linklerini alma işleminin gerçekleştiği metottur.
public static async Task<PuppeteerDataResult<List<string>>> GetVideoSearchVideoResultUrlList(string url, string searchWord) | |
{ | |
using (var page = await OpenChromiumPage()) | |
{ | |
try | |
{ | |
WaitUntilNavigation[] waitUntil = new[] { WaitUntilNavigation.Networkidle0, WaitUntilNavigation.Networkidle2, WaitUntilNavigation.DOMContentLoaded, WaitUntilNavigation.Load }; | |
await page.GoToAsync(url, new NavigationOptions { WaitUntil = waitUntil }); | |
await SearchOnGoogle(searchWord, page); | |
//Click Video Tab | |
var videoTabElement = @"document.getElementsByClassName('hdtb-mitem')[4].getElementsByTagName('a')[0].href"; | |
var videoTabLink = await page.EvaluateExpressionAsync<string>(videoTabElement); | |
await page.GoToAsync(videoTabLink, new NavigationOptions { WaitUntil = waitUntil }); | |
var result = await VideoLinkList(page); | |
return new SuccessPuppeteerDataResult<List<string>>(result, "Get Title Successfully"); | |
} | |
catch (Exception ex) | |
{ | |
return new ErrorPuppeteerDataResult<List<string>>("Error Occured! Detail: " + ex.Message); | |
} | |
finally | |
{ | |
CloseChromium(page); | |
} | |
} | |
} |
- SearchOnGoogle: Google sitesindeki arama textbox ile arama yap butonuna ait HTML name özelliğini kullanarak arama yapma işlemini yapacaktır.
Yukarıdaki görselde yazılan javascript kodu, video sekmesine ait linki alır. hdtb-mitem adındaki sınıfın a elementindeki href özelliğini alır. Aşağıdaki görselde F12 ye tıklayarak hedeflenen elementin id, class veya name bilgisini bulabiliriz.
public static async Task<List<string>> VideoLinkList(Page page) | |
{ | |
WaitUntilNavigation[] waitUntil = new[] { WaitUntilNavigation.Networkidle0, WaitUntilNavigation.Networkidle2, WaitUntilNavigation.DOMContentLoaded, WaitUntilNavigation.Load }; | |
var next = @"document.getElementById('pnnext')"; | |
var nexts = await page.EvaluateExpressionAsync<object>(next); | |
var linkList = new List<string>(); | |
var isLastPage = (nexts == null); | |
while ((nexts != null) || !isLastPage) | |
{ | |
var jsSelectAllAnchors = @"Array.from(document.querySelectorAll('.g'))"; | |
var urls = await page.EvaluateExpressionAsync<object[]>(jsSelectAllAnchors); | |
for (int i = 0; i < urls.Length; i++) | |
{ | |
var query = $"document.querySelectorAll('.g')[{i}].getElementsByTagName('a')[0].href"; | |
linkList.Add(await page.EvaluateExpressionAsync<string>(query)); | |
} | |
nexts = await page.EvaluateExpressionAsync<object>(next); | |
if (nexts != null) | |
{ | |
var nextHref = @"document.getElementById('pnnext').href"; | |
var nextHrefUrl = await page.EvaluateExpressionAsync<string>(nextHref); | |
isLastPage = (nexts == null) && !string.IsNullOrEmpty(nextHrefUrl); | |
await page.GoToAsync(nextHrefUrl, new NavigationOptions { WaitUntil = waitUntil }); | |
nexts = await page.EvaluateExpressionAsync<object>(next); | |
} | |
else | |
{ | |
isLastPage = true; | |
} | |
} | |
return linkList; | |
} |
- VideoLinkList metodu, arama sonuçlarındaki video url listesini döndürecek bir liste döndürür. Video linklerini alabilmemiz için HTML elementleri okumaya yarayan javascript kodlarını almalıyız. Bunun için selector - seçicilerden faydalanırız.
Bu işlemi yaparken aynı zamanda diğer sayfalardaki linkleri de gezmemiz gerekecek. Son sayfaya gelene kadar pnnext idsine sahip element olup olmadığı metottaki döngüde kontrol edilir. Bu element Sonraki linkine ait id selector'dir.
EvaluateExpressionAsync metodu ile javascript kodlarını değerlendirmeye devam ediyoruz. Javascript syntax hatası yaptığımızda aşağıdaki gibi hata verecektir. Bu nedenle doğru bir şekilde yazmaya dikkat edilmelidir.
- CloseChromium metodu Page tipinde bir değer alıp eğer sayfa açıksa tarayıcıyı kapatacaktır. - CloseAsync metodu - Eğer açık olan bir sayfamız varsa kapatma işleminin de yapılması gerekir. Böyle arka planda açık tarayıcı kalmayacaktır. PuppeteerSharp metotları ile işimiz bittikten sonra bu metodu istediğimiz yere yerleştirebiliriz.
public static async void CloseChromium(Page page) | |
{ | |
if (!page.IsClosed && page != null) | |
{ | |
await page.Browser.CloseAsync(); | |
} | |
} |
Uyarı: İster Google ister farklı bir sayfada HTML sayfasında seçicilerde değişiklik olursa hata verebilir ya da istenilen sonuç alınmayabilir. Muhtemel hatada, Normal bir tarayıcıda F12 ile kaynağı görüntüleyerek HTML elementinde bir değişiklik olup olmadığını tespit edebilirsiniz.
Github hesabımda bu örneğin ve PuppeteerSharp ile yaptığım diğer örnekleri bulabilirsiniz.
Projeye ait Github Linkleri
- NET 5 ile geliştirlen repository: PuppeteerSharpTutorialDotNetCore
- NET Framework ile geliştirlen repository: PuppeteerSharpTutorial
Ayrıca eğer Puppeteer ile çalışmak isterseniz bu kütüphaneye ait linklerden de yararlanabilirsiniz.
https://github.com/hardkoded/puppeteer-sharp
https://www.puppeteersharp.com/examples/index.html
Herkese iyi kodlamalar :)
Yorumlar
Yorum Gönder