diff --git a/src/fundus/parser/utility.py b/src/fundus/parser/utility.py index 614feddad..cb4990cf1 100644 --- a/src/fundus/parser/utility.py +++ b/src/fundus/parser/utility.py @@ -734,6 +734,7 @@ def parse_versions(img_node: lxml.html.HtmlElement, size_pattern: Optional[Patte and not default_width == "auto" and (default_height := img_node.get("height")) and not default_height == "auto" + and not float(default_height) == 0.0 ): ratio = float(default_width) / float(default_height) else: diff --git a/src/fundus/publishers/tr/__init__.py b/src/fundus/publishers/tr/__init__.py index 9dce06c97..1974665f0 100644 --- a/src/fundus/publishers/tr/__init__.py +++ b/src/fundus/publishers/tr/__init__.py @@ -27,6 +27,7 @@ class TR(metaclass=PublisherGroup): name="NTVTR", domain="https://www.ntv.com.tr/", parser=NTVTRParser, + url_filter=regex_filter("/galeri/"), # Exclude galleries sources=[ RSSFeed("https://www.ntv.com.tr/gundem.rss"), NewsMap("https://www.ntv.com.tr/sitemaps/news-sitemap.xml"), diff --git a/src/fundus/publishers/tr/ntvtr.py b/src/fundus/publishers/tr/ntvtr.py index e4a86f81b..bb233cd69 100644 --- a/src/fundus/publishers/tr/ntvtr.py +++ b/src/fundus/publishers/tr/ntvtr.py @@ -1,4 +1,5 @@ import datetime +import re from typing import List, Optional from lxml.cssselect import CSSSelector @@ -11,13 +12,16 @@ generic_date_parsing, generic_topic_parsing, image_extraction, + strip_nodes_to_text, ) class NTVTRParser(ParserProxy): class V1(BaseParser): - _paragraph_selector = CSSSelector("div.content-news-tag-selector > p") - _summary_selector = CSSSelector("h2.category-detail-sub-title") + VALID_UNTIL = datetime.date(2025, 11, 4) + + _paragraph_selector = XPath("//div[@class='content-news-tag-selector']/p") + _summary_selector = XPath("//h2[@class='category-detail-sub-title']") @attribute def body(self) -> Optional[ArticleBody]: @@ -33,7 +37,9 @@ def publishing_date(self) -> Optional[datetime.datetime]: @attribute def title(self) -> Optional[str]: - return self.precomputed.meta.get("og:title") + if title := self.precomputed.meta.get("og:title"): + return title.replace("| NTV Haber", "").strip() + return None @attribute def topics(self) -> List[str]: @@ -52,3 +58,40 @@ def images(self) -> List[Image]: lower_boundary_selector=CSSSelector("div.social:last-of-type"), image_selector=XPath("//div[contains(@class, 'img-wrapper')]//img | //picture /img"), ) + + class V1_1(V1): + VALID_UNTIL = datetime.date.today() + + _paragraph_selector = XPath("//div[contains(@class, 'content')]/p[text()]") + _summary_selector = XPath("//h2") + _subheadline_selector = XPath("//div[contains(@class, 'content')]/p[not(text()) and strong]") + + _topics_selector = XPath("(//ul[contains(@class, 'text-[#3D619B]')])[1]/li") + + @attribute + def body(self) -> Optional[ArticleBody]: + return extract_article_body_with_selector( + self.precomputed.doc, + paragraph_selector=self._paragraph_selector, + summary_selector=self._summary_selector, + subheadline_selector=self._subheadline_selector, + ) + + @attribute + def topics(self) -> List[str]: + return generic_topic_parsing( + strip_nodes_to_text(self._topics_selector(self.precomputed.doc), join_on=","), + substitution_pattern=re.compile(r"-\s*$"), + delimiter=",", + ) + + @attribute + def images(self) -> List[Image]: + return image_extraction( + doc=self.precomputed.doc, + paragraph_selector=self._paragraph_selector, + upper_boundary_selector=CSSSelector("h1"), + lower_boundary_selector=XPath("(//img[@alt='Google Play'])[1]"), + image_selector=XPath("//div[@property='articleBody']//img[not(@fetchpriority='auto')]"), + author_selector=XPath("./ancestor::div[contains(@class,'relative') and (picture or img)]/div"), + ) diff --git a/tests/resources/parser/test_data/tr/NTVTR.json b/tests/resources/parser/test_data/tr/NTVTR.json index 40e35d2a8..5f880d83f 100644 --- a/tests/resources/parser/test_data/tr/NTVTR.json +++ b/tests/resources/parser/test_data/tr/NTVTR.json @@ -89,5 +89,96 @@ "Galatasaray", "Fenerbahçe" ] + }, + "V1_1": { + "authors": [ + "ntv.com.tr" + ], + "body": { + "summary": [ + "İstanbul'da, Ozan Elektronik Para AŞ üzerinden yasa dışı yollarla elde edilen gelirleri akladıkları iddiasıyla gözaltına alınan 15 şüpheliden 4'ü tutuklandı." + ], + "sections": [ + { + "headline": [], + "paragraphs": [ + "İstanbul Cumhuriyet Başsavcılığınca \"Terörizmin Finansmanının Önlenmesi ve Aklama Suçu Soruşturma Bürosu\"nca, \"suç işlemek amacıyla örgüt kurma\", \"yasa dışı bahis\", \"tefecilik\" ile \"suçtan kaynaklanan mal varlığı değerlerini aklama\" suçlarına yönelik yürütülen soruşturmada, Ozan Elektronik Para AŞ'nin üzerinden \"7258 Sayılı Futbol ve Diğer Spor Müsabakalarında Bahis ve Şans Oyunları Düzenlenmesi Hakkında Kanun'a muhalefet\" edilerek elde edilen suç gelirleri ile \"pos tefeciliği\" suçlarına ilişkin başlatılan soruşturma sürüyor.", + "Soruşturma kapsamında gözaltına alınan 15 şüphelinin emniyetteki işlemleri tamamlandı.", + "Şüpheliler sağlık kontrollerinin ardından adliyeye sevk edildi.", + "Savcılıkta ifade veren şüphelilerden 9'u tutuklama, 6'sı ise adli kontrol talebiyle sulh ceza hakimliğine sevk edildi.", + "Hakimlik 4 şüphelinin tutuklanmasına, 11 şüpheli hakkında ise adli kontrol tedbiri uygulanmasına hükmetti." + ] + }, + { + "headline": [ + "NE OLMUŞTU?" + ], + "paragraphs": [ + "Başsavcılıktan yapılan açıklamada, Terörizmin Finansmanının Önlenmesi ve Aklama Suçu Soruşturma Bürosunca, \"suç işlemek amacıyla örgüt kurma\", \"yasa dışı bahis\", \"tefecilik\" ile \"suçtan kaynaklanan mal varlığı değerlerini aklama\" suçlarına yönelik yürütülen soruşturmada, Ozan Elektronik Para AŞ üzerinden \"7258 Sayılı Futbol ve Diğer Spor Müsabakalarında Bahis ve Şans Oyunları Düzenlenmesi Hakkında Kanun'a muhalefet\" edilerek elde edilen suç gelirleri ile \"pos tefeciliği\" suçlarından kaynaklanan gelirlerin aklanmasına yönelik kuvvetli suç şüphesi tespit edildiği belirtilmişti.", + "Açıklamada, yürütülen mali incelemelerde, şirketin elektronik para kuruluşu statüsünün suçtan kaynaklanan mal varlığı değerlerinin meşru ticari faaliyet izlenimi altında finansal sisteme sokulması için kullanıldığının değerlendirildiği aktarılmıştı.", + "Soruşturma kapsamında MASAK, Türkiye Cumhuriyet Merkez Bankası ve bağımsız denetim kuruluşları tarafından hazırlanan raporların incelendiği ifade edilen açıklamada, suç gelirlerinin sanal POS cihazları üzerinden aktarılarak sisteme dahil edildiğinin anlaşıldığı kaydedilmişti.", + "Açıklamada, raporlarda, Libya ve Irak gibi yüksek riskli ülkelerden gelen, kartlarla yapılan, tekrarlayan yüksek tutarlı işlemlerin engellenmediği, alarm üretilmesine rağmen gerekli aksiyonların alınmadığı, aynı kartların farklı üye iş yerlerinde kısa aralıklarla kullanıldığı, bu durumun gerçek ticari faaliyetten ziyade para aktarımı ve pos tefeciliği niteliği taşıdığının tespit edildiği belirtilmişti.", + "Ayrıca, Ozan Elektronik Para AŞ'nin sahibi Ozan Özerk'in ortağı olduğu Aveon Global Sigorta AŞ üzerinden \"sigorta primi\" adı altında para akışı sağlandığı, söz konusu şirketin Londra merkezli Aveon Global Holding üzerinden kontrol edildiği, suç gelirlerinin sigorta primi veya ticari işlem görünümü verilerek finansal sisteme dahil edilip aklandığı vurgulanmıştı." + ] + }, + { + "headline": [ + "402 MİLYON LİRALIK MAL VARLIĞINA EL KONULMUŞTU" + ], + "paragraphs": [ + "Bu kapsamda yürütülen mali analizler neticesinde 7 şirket, 3 konut, 5 arsa ve 4 araca ait toplamda yaklaşık 402 milyon lira değerinde mal varlığı tespit edildiği belirtilen açıklamada, haklarında gözaltı kararı verilen 10 şüpheli ve 7 şirkete yönelik eş zamanlı operasyon düzenlendiği ve mal varlıklarına el koyma işlemleri gerçekleştirildiği kaydedilmişti.", + "Açıklamada, suçtan elde edildiği değerlendirilen gelirlerin finansal sisteme dahil edilmesinde aktif rol oynadığı belirlenen Ozan Elektronik Para AŞ'ye, İstanbul Nöbetçi Sulh Ceza Hakimliğince mali yapının korunması ve delil karartılmasının önlenmesi amacıyla Tasarruf Mevduatı Sigorta Fonu (TMSF) tarafından kayyım atanmasına karar verildiği ifade edilmişti.", + "Sulh ceza hakimliği gözaltı kararı verilen 6 şüphelinin tutuklanmasına, 2 şüpheli hakkında ise adli kontrol tedbiri uygulanmasına karar vermişti. Soruşturma kapsamında, yurt dışında bulundukları tespit edilen 2 şüpheli hakkında ise yakalama kararı çıkarılmıştı." + ] + }, + { + "headline": [ + "İKİNCİ OPERASYON" + ], + "paragraphs": [ + "Soruşturma kapsamında pos tefeciliği ve suç gelirlerinin aklanması eylemlerine yalnızca şirket üst yönetiminin değil, şirketin farklı birimlerinde görev alan, eski yönetim kurulu üyeleri, bilgi teknoloji birimi çalışanları, risk yönetimi ve iç denetim personeli, yazılım geliştirme uzmanları ile finans ve muhasebe yöneticilerinin de iştirak ettiği yönünde kuvvetli bulgular elde edilmişti.", + "Bu kapsamda tespit edilen 16 zanlıdan 15'i gözaltına alınırken, soruşturmada şüphelilerin öncül suç tarihlerinden sonra edindikleri 2 konut, 2 arsa ve 3 araca yönelik toplam 72 milyon lira değerindeki mal varlığına sulh ceza hakimliği kararınca el konulmuştu." + ] + } + ] + }, + "images": [ + { + "versions": [ + { + "url": "https://images.ntv.com.tr/images/135724d5-eb44-4ad7-a93c-e8d021e23da1.jpg?width=375&height=211&format=webp", + "query_width": null, + "size": { + "width": 375, + "height": 211 + }, + "type": "image/jpeg" + }, + { + "url": "https://images.ntv.com.tr/images/135724d5-eb44-4ad7-a93c-e8d021e23da1.jpg?width=930&height=523&format=webp", + "query_width": "min-width:1200", + "size": { + "width": 930, + "height": 523 + }, + "type": "image/jpeg" + } + ], + "is_cover": true, + "description": "\"Pos tefeciliği\" soruşturması: 4 şüpheli tutuklandı", + "caption": null, + "authors": [ + "Anadolu Ajansı" + ], + "position": 197 + } + ], + "publishing_date": "2025-11-10 17:59:02+03:00", + "title": "\"Pos tefeciliği\" soruşturması: 4 şüpheli tutuklandı", + "topics": [ + "Tefecilik", + "Soruşturma", + "Tutuklama" + ] } } diff --git a/tests/resources/parser/test_data/tr/NTVTR_2025_11_10.html.gz b/tests/resources/parser/test_data/tr/NTVTR_2025_11_10.html.gz new file mode 100644 index 000000000..1f46696cf Binary files /dev/null and b/tests/resources/parser/test_data/tr/NTVTR_2025_11_10.html.gz differ diff --git a/tests/resources/parser/test_data/tr/meta.info b/tests/resources/parser/test_data/tr/meta.info index b34c9facf..7b07eccd2 100644 --- a/tests/resources/parser/test_data/tr/meta.info +++ b/tests/resources/parser/test_data/tr/meta.info @@ -10,5 +10,9 @@ "NTVTR_2024_04_30.html.gz": { "url": "https://www.ntv.com.tr/sporskor/super-ligde-golculerin-yarisi-kiyasiya,2dwxjsYnL0-RnLe_r91pqg", "crawl_date": "2024-04-30 15:50:13.612700" + }, + "NTVTR_2025_11_10.html.gz": { + "url": "https://www.ntv.com.tr/turkiye/pos-tefeciligi-sorusturmasi-4-supheli-tutuklandi-1695518", + "crawl_date": "2025-11-10 20:23:19.864952" } }