From 4c8561169d4c0b0e887a4e2c1485104121208928 Mon Sep 17 00:00:00 2001 From: Yuval Adam Date: Sat, 25 Jan 2014 00:54:33 +0100 Subject: Add Ynet parsing --- .../0007_auto__add_ynetarticle__add_ynetimage.py | 120 +++ newsdiff/core/models.py | 25 + newsdiff/core/parsers/base.py | 9 +- newsdiff/core/parsers/haaretz.py | 7 +- newsdiff/core/parsers/ynet.py | 56 ++ newsdiff/core/tasks.py | 13 + newsdiff/core/tests/content/0,7340,L-2,00.html | 455 ++++++++++ newsdiff/core/tests/content/4480544.html | 965 +++++++++++++++++++++ newsdiff/core/tests/haaretz_tests.py | 44 + newsdiff/core/tests/tests.py | 44 - newsdiff/core/tests/ynet_tests.py | 35 + newsdiff/settings/base.py | 4 + 12 files changed, 1725 insertions(+), 52 deletions(-) create mode 100644 newsdiff/core/migrations/0007_auto__add_ynetarticle__add_ynetimage.py create mode 100644 newsdiff/core/parsers/ynet.py create mode 100644 newsdiff/core/tests/content/0,7340,L-2,00.html create mode 100644 newsdiff/core/tests/content/4480544.html create mode 100644 newsdiff/core/tests/haaretz_tests.py delete mode 100644 newsdiff/core/tests/tests.py create mode 100644 newsdiff/core/tests/ynet_tests.py diff --git a/newsdiff/core/migrations/0007_auto__add_ynetarticle__add_ynetimage.py b/newsdiff/core/migrations/0007_auto__add_ynetarticle__add_ynetimage.py new file mode 100644 index 0000000..c04d291 --- /dev/null +++ b/newsdiff/core/migrations/0007_auto__add_ynetarticle__add_ynetimage.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'YnetArticle' + db.create_table(u'core_ynetarticle', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('url', self.gf('django.db.models.fields.CharField')(max_length=250)), + ('ynet_id', self.gf('django.db.models.fields.CharField')(unique=True, max_length=9, db_index=True)), + ('title', self.gf('django.db.models.fields.CharField')(max_length=200)), + ('subtitle', self.gf('django.db.models.fields.CharField')(max_length=1000, null=True, blank=True)), + ('author', self.gf('django.db.models.fields.CharField')(max_length=60)), + ('text', self.gf('django.db.models.fields.TextField')()), + ('date', self.gf('django.db.models.fields.DateTimeField')()), + )) + db.send_create_signal(u'core', ['YnetArticle']) + + # Adding model 'YnetImage' + db.create_table(u'core_ynetimage', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('article', self.gf('django.db.models.fields.related.ForeignKey')(related_name='images', to=orm['core.YnetArticle'])), + ('origin_url', self.gf('django.db.models.fields.CharField')(unique=True, max_length=250)), + ('image', self.gf('django.db.models.fields.files.ImageField')(max_length=100)), + ('caption', self.gf('django.db.models.fields.CharField')(max_length=140, null=True, blank=True)), + )) + db.send_create_signal(u'core', ['YnetImage']) + + + def backwards(self, orm): + # Deleting model 'YnetArticle' + db.delete_table(u'core_ynetarticle') + + # Deleting model 'YnetImage' + db.delete_table(u'core_ynetimage') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'core.haaretzarticle': { + 'Meta': {'object_name': 'HaaretzArticle'}, + 'author': ('django.db.models.fields.CharField', [], {'max_length': '60'}), + 'date': ('django.db.models.fields.DateTimeField', [], {}), + 'haaretz_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '12', 'db_index': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'subtitle': ('django.db.models.fields.CharField', [], {'max_length': '1000', 'null': 'True', 'blank': 'True'}), + 'text': ('django.db.models.fields.TextField', [], {}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}), + 'url': ('django.db.models.fields.CharField', [], {'max_length': '250'}) + }, + u'core.haaretzimage': { + 'Meta': {'object_name': 'HaaretzImage'}, + 'article': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'images'", 'to': u"orm['core.HaaretzArticle']"}), + 'caption': ('django.db.models.fields.CharField', [], {'max_length': '140', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}), + 'origin_url': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '250'}) + }, + u'core.newsdiffuser': { + 'Meta': {'object_name': 'NewsDiffUser'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'core.ynetarticle': { + 'Meta': {'object_name': 'YnetArticle'}, + 'author': ('django.db.models.fields.CharField', [], {'max_length': '60'}), + 'date': ('django.db.models.fields.DateTimeField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'subtitle': ('django.db.models.fields.CharField', [], {'max_length': '1000', 'null': 'True', 'blank': 'True'}), + 'text': ('django.db.models.fields.TextField', [], {}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}), + 'url': ('django.db.models.fields.CharField', [], {'max_length': '250'}), + 'ynet_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '9', 'db_index': 'True'}) + }, + u'core.ynetimage': { + 'Meta': {'object_name': 'YnetImage'}, + 'article': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'images'", 'to': u"orm['core.YnetArticle']"}), + 'caption': ('django.db.models.fields.CharField', [], {'max_length': '140', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}), + 'origin_url': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '250'}) + } + } + + complete_apps = ['core'] \ No newline at end of file diff --git a/newsdiff/core/models.py b/newsdiff/core/models.py index 6c3e7aa..711a32f 100644 --- a/newsdiff/core/models.py +++ b/newsdiff/core/models.py @@ -32,3 +32,28 @@ class HaaretzImage(models.Model): def __unicode__(self): return self.origin_url + + +class YnetArticle(models.Model): + url = models.CharField(max_length=250) + ynet_id = models.CharField(max_length=9, unique=True, db_index=True) + title = models.CharField(max_length=200) + subtitle = models.CharField(max_length=1000, blank=True, null=True) + author = models.CharField(max_length=60) + text = models.TextField() + date = models.DateTimeField() + + def __unicode__(self): + return self.url + +reversion.register(YnetArticle) + + +class YnetImage(models.Model): + article = models.ForeignKey(YnetArticle, related_name='images') + origin_url = models.CharField(max_length=250, unique=True) + image = models.ImageField(upload_to='images/ynet') + caption = models.CharField(max_length=140, blank=True, null=True) + + def __unicode__(self): + return self.origin_url diff --git a/newsdiff/core/parsers/base.py b/newsdiff/core/parsers/base.py index 532568a..d741683 100644 --- a/newsdiff/core/parsers/base.py +++ b/newsdiff/core/parsers/base.py @@ -17,6 +17,12 @@ class HtmlSoupParser(object): req = requests.get(url, headers=self.HTTP_HEADERS) return BeautifulSoup(req.text, 'lxml') + def parse_homepage(self, soup): + links = soup.find_all('a', href=self.ARTICLE_HREF_PATTERN) + hrefs = [link['href'] for link in links] + article_urls = list(set(map(self.clean_article_href, hrefs))) + return article_urls + def process_homepage(self): soup = self.get_page(self.HOMEPAGE_URL) articles = self.parse_homepage(soup) @@ -26,9 +32,6 @@ class HtmlSoupParser(object): soup = self.get_page(url) self.parse_article(url, soup) - def parse_homepage(self, soup): - raise NotImplementedError - def parse_article(self, url, soup): raise NotImplementedError diff --git a/newsdiff/core/parsers/haaretz.py b/newsdiff/core/parsers/haaretz.py index 8928663..f76a01e 100644 --- a/newsdiff/core/parsers/haaretz.py +++ b/newsdiff/core/parsers/haaretz.py @@ -20,11 +20,8 @@ class HaaretzParser(HtmlSoupParser): ARTICLE_MODEL = HaaretzArticle IMAGE_MODEL = HaaretzImage - def parse_homepage(self, soup): - links = soup.find_all('a', href=self.ARTICLE_HREF_PATTERN) - hrefs = [link['href'] for link in links] - article_urls = list(set(map(self.clean_article_href, hrefs))) - return article_urls + def article_id_to_url(self, article_id): + return '{}/{}'.format(self.BASE_URL, article_id) def parse_article(self, url, soup): haaretz_id = re.findall(self.ARTICLE_ID_PATTERN, url)[0] diff --git a/newsdiff/core/parsers/ynet.py b/newsdiff/core/parsers/ynet.py new file mode 100644 index 0000000..112c0bd --- /dev/null +++ b/newsdiff/core/parsers/ynet.py @@ -0,0 +1,56 @@ +import re +import requests +import reversion + +from bs4 import BeautifulSoup +from datetime import datetime +from django.db import transaction + +from .base import HtmlSoupParser +from ..models import YnetArticle, YnetImage +from ..utils import get_file_from_url + + +class YnetParser(HtmlSoupParser): + + BASE_URL = 'http://www.ynet.co.il' + HOMEPAGE_URL = BASE_URL + '/home/0,7340,L-2,00.html' + ARTICLE_HREF_PATTERN = re.compile(r'''^(http:\/\/www\.ynet\.co\.il)?/articles/0,7340,L-\d\d\d\d\d\d\d,00\.html$''') + ARTICLE_ID_PATTERN = re.compile(r'\d\d\d\d\d\d\d') + ARTICLE_MODEL = YnetArticle + IMAGE_MODEL = YnetImage + + def article_id_to_url(self, article_id): + return self.HOMEPAGE_URL.replace('L-2', 'L-{}'.format(article_id)) + + def parse_article(self, url, soup): + ynet_id = re.findall(self.ARTICLE_ID_PATTERN, url)[0] + title = soup.find('div', class_='art_header_title').text.strip() + subtitle = soup.find('div', class_='art_header_sub_title').text.strip() + author_bar = soup.find('span', class_='art_header_footer_author') + author = author_bar.find('a').text.strip() + date = re.findall(r'\d\d.\d\d.\d\d', author_bar.text)[0] + time = re.findall(r'\d\d:\d\d', author_bar.text)[0] + article_date = self.TIMEZONE.localize(datetime.strptime(' '.join([date, time]), '%d.%m.%y %H:%M')) + article_body = soup.find('div', class_='art_body').find_all('p') + article_text = '\n'.join([p.text.strip() for p in article_body]) + + with transaction.atomic(), reversion.create_revision(): + try: + existing_article = self.ARTICLE_MODEL.objects.get(ynet_id=ynet_id) + changed = False + if title != existing_article.title: + existing_article.title = title + changed = True + if subtitle != existing_article.subtitle: + existing_article.subtitle = subtitle + changed = True + if article_text != existing_article.text: + existing_article.text = text + changed = True + if changed: + existing_article.save() + except self.ARTICLE_MODEL.DoesNotExist: + article = self.ARTICLE_MODEL(url=url, ynet_id=ynet_id, title=title, + subtitle=subtitle, author=author, text=article_text, date=article_date) + article.save() diff --git a/newsdiff/core/tasks.py b/newsdiff/core/tasks.py index 34e12ac..784fd28 100644 --- a/newsdiff/core/tasks.py +++ b/newsdiff/core/tasks.py @@ -2,6 +2,7 @@ import logging from newsdiff.celery import app from newsdiff.core.parsers.haaretz import HaaretzParser +from newsdiff.core.parsers.ynet import YnetParser @app.task() def process_haaretz_homepage(): @@ -14,3 +15,15 @@ def process_haaretz_homepage(): def process_haaretz_article(url): hp = HaaretzParser() hp.process_article(url) + +@app.task() +def process_ynet_homepage(): + yp = YnetParser() + articles = yp.process_homepage() + for article_url in articles: + process_ynet_article.delay(article_url) + +@app.task(rate_limit='12/m') +def process_ynet_article(url): + yp = YnetParser() + yp.process_article(url) \ No newline at end of file diff --git a/newsdiff/core/tests/content/0,7340,L-2,00.html b/newsdiff/core/tests/content/0,7340,L-2,00.html new file mode 100644 index 0000000..026b87e --- /dev/null +++ b/newsdiff/core/tests/content/0,7340,L-2,00.html @@ -0,0 +1,455 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +ynet - חדשות + + +
+
 
לכל המבזקים
25/01/2014 00:1925/01/2014 00:1925/01/2014 00:19 +
 

קרי: בידוד ישראל יסכן את כלכלתה
מזכיר המדינה הזהיר בדאבוס מפני ההשלכות שיהיו לכישלון השיחות עם הפלסטינים: "כלכלת ישראל היא פלא מרשים, אך הביטחון המידרדר והגברת הבידוד עלולים לסכן זאת". עוד אמר: "ישראל מסרבת בצדק לצאת מהגדה לפני שתוודא שלא תהיה עוד עזה"
לסיפור המלא. . . 
ג'ון קרי (צילום: AP)
+ + +
+ + +
+
אינטרנט  |  ynet  |  בעלי מקצוע  |  קניות
|שלום אורח
התחבר
|הירשמו ל-ynet
+

+ + + + +
+ + + + +

חדשות

   + + + + + חדשות תוכן ועדכונים 24 שעות - Ynet
הפכו ערוץ זה לדף הבית שלכם
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + +
צילום אילוסטרציה: AP
 
"התנתקתי. ילדתי בשביל הכסף"
 
מה עובר על אמהות פונדקאיות שנושאות תינוק זר? "מפריטים את הגוף בשביל כסף", יש המאשימים, אחרים טוענים: "זו עוצמה נשית". ויש גם עדות  
אוניית חיל הים (צילום: התעשייה האווירית לישראל)
 
חיילים נפגעו בשריפה על ספינה
 
15 חיילים נפגעו קל-בינוני בדלקה שפרצה על אוניית חיל הים בדרום. רק השבוע התהפכה "צרעה" של חיל הים באותו אזור (יואב זיתון)
פיצוץ בדאחייה (צילום: AFP)
 
חדש בלבנון: אפליקציית "אני חי"
 
אחרי כל פיגוע בלבנון, קווי הטלפון קורסים בשל העומס. אז הלבנונים נוהרים לאפליקציה חדשה שמודיעה דרך הסמארטפון: "אני חי!" (רועי קייס)
האב ובתו (צילום: AP)
 
הון למי שיהפוך בתי לסטרייטית
 
מיליארדר מהונג קונג הכפיל את הסכום שייתן לגבר ש"ימיר" את בתו הלסבית. הפרס החדש - 130 מיליון דולר. מה היא ובת זוגה חושבות על זה?
פוליטי מדיני ביטחוני
דיווח: הרוג ופצוע מאש צה"ל בגבול עזה
אליאור לוי ויואב זיתון (16:54 , 24.01.14 )
"מי שרוצה להיות צודק, שיעשה צדק לזולתו"
ynet (13:03 , 24.01.14 )
כבוד לפרס בוועידה: קיבל אות "רוח דאבוס"
נועם (דבול) דביר (11:12 , 24.01.14 )
רעייתו של יו"ר הכנסת הלכה לעולמה בגיל 63
מורן אזולאי (10:31 , 24.01.14 )
סופדים לשולמית אלוני: 'מגדלור ומצפן מוסרי'
כתבי ynet (09:58 , 24.01.14 )
בכיר אש"ף חושף: תוכנית קרי ודרישות ישראל
אליאור לוי (09:43 , 24.01.14 )
צה"ל שוקל: ג'ובניקים ישרתו פחות
יוסי יהושוע, "ידיעות אחרונות" (08:50 , 24.01.14 )
שולמית אלוני הלכה לעולמה והיא בת 85
ירון דרוקמן (08:07 , 24.01.14 )
נציב קבילות החיילים נזף במפקד מגלן: לוחם הפך לעקר
יואב זיתון (21:24 , 23.01.14 )
לבנונים בבסיס: מסר לחיזבאללה בראיון נדיר
רועי קייס (21:20 , 23.01.14 ) 
עוד פוליטי-מדיני

חדשות בארץ
רוכב אופנוע נהרג מפגיעת רכב ברחובות
אלי סניור (03:05 , 24.01.14 )
ההרעלה הקטלנית בירושלים: השאלות הקשות
נועם (דבול) דביר (00:38 , 24.01.14 ) 
גולן עבר פוליגרף: 'ידעת שהן לא בנות 16?'
אלי סניור (00:27 , 24.01.14 )
ברבי לא יואשם בהריגה: "כואב לנו, אין צדק"
מיכל מרגלית (00:17 , 24.01.14 )
נצרת סוערת: "הבחירות עוד יגרמו למלחמה"
חסן שעלאן (21:29 , 23.01.14 )
קבר בנותיו, יבקר את בניו: "מצבם לא פשוט"
נועם (דבול) דביר, ירון קלנר ורענן בן צור (19:44 , 23.01.14 ) 
"אל תדאגי, זה ייקח 5 דקות". העדות של גולן
יורם ירקוני, "ידיעות אחרונות" (19:30 , 23.01.14 )
נדחו בקשות לחייב הוצאת דרכון לילדי תאילנד
מיכל מרגלית (18:37 , 23.01.14 )
אותו המדביר: חשש שאם ובתה הורעלו
נועם (דבול) דביר (18:29 , 23.01.14 ) 
מחוקק קנדי גילה בארץ תמונת קרובתו מהגטו
אחיה ראב"ד (15:04 , 23.01.14 )
עוד חדשות בארץ

חדשות בעולם
עירום בשלג הכבד: השפלה למפגין האוקראיני
סוכנויות הידיעות (19:23 , 24.01.14 )
סוריה: 63 פלסטינים מתו במצור של אסד
AP (18:40 , 24.01.14 )
הפנטגון מודה: ארה"ב לוקה באיתור גרעין זר
יצחק בן-חורין, וושינגטון (13:58 , 24.01.14 )
טרור בלב קהיר: 5 הרוגים, עשרות פצועים
רועי קייס וסוכנויות הידיעות (07:34 , 24.01.14 ) 
לקראת האולימפיאדה: ברוסיה מלמדים לחייך
רויטרס (06:23 , 24.01.14 )
נרצח בלגי שאכל ב-100 מסעדות ולא שילם
AP (04:34 , 24.01.14 )
נתפס נאשם בשוד "החבר'ה הטובים" מ-78'
סוכנויות הידיעות (04:10 , 24.01.14 )
החמקן לא אמין: תקלות קשות ב-F-35
יואב זיתון ורויטרס (00:32 , 24.01.14 )
'אין סיכוי להסכם'. רוחאני זעזע את כתב CNN
יצחק בן חורין, וושינגטון (00:31 , 24.01.14 ) 
סימנים של שלום? הפסקת אש בדרום סודן
AP (00:20 , 24.01.14 )
עוד חדשות בעולם

צילום: ירון ברנר
ה'פרילנסרים' של הרקטות על הכוונת

ירון פרידמן
בין סוריה לז'נבה. כישלון הוועידה ידוע מראש

צילום: גבי מנשה
מה בוער עם היועמ"ש


מאה על 100


+ +
חדשות השבוע
כותרות השבוע האחרון שהתפרסמו ב-ynet
+ +
פרויקטים
רון בן ישי בן 70
40 ליום כיפור
השנה שלנו
גולני
מפת החינוך
+ + + + + + + +
 פורומים
+חדר החדשות
פוליטיקה
ההתנחלויות
צו קריאה
+

+

לחצו כאן להרשמה לניוזלטר

+ + + + + + + + + + + + +
+ +
+
+ + +

מזג האוויר

מפת הפקקים

בלוגוס

+ +
תמונת היום
צילום: AFP
אגוזי הבירה
מיוחד
השמות שלנו
לראשונה: השמות של המדינה, מכל שנה
ירון דרוקמן
לוחמים בפשע מיובשים מול קובצי אקסל
אלי סניור
ההרעלה בירושלים: השאלות הקשות
נועם (דבול) דביר  
המפקדים התעלמו, לוחם צנחנים מת מסרטן
יואב זיתון  
תיעוד: מטפלת גררה, היכתה והשפילה קשישה
מתן צורי  
למען השם: למה יש יותר מזרחים מפרידמנים?
מיכל מרגלית
חיסול הנקמה הישראלי שהדהים את ערפאת
ירון דרוקמן
רצחו את הבן שלי ואז ערפו לו את הראש
אלי סניור  
הזרים בת"א עייפים ומחפשים "יהודי אמיתי"
רועי מנדל  
הדיור הציבורי קרוב? "הוציאו לי את הנשמה"
מיכל מרגלית
ירייה בברך או שתיים בבטן? וידוי הנסחט
נעמה כהן פרידמן

טרווליסט

חדשות
דעות
ספורט
כלכלה
צרכנות
תרבות ובידור
מחשבים
בריאות
ירוק
יהדות
תיירות
רכב
אוכל
יחסים
רכילות
סרטים
הוט
כלכליסט
משחקים
מקומי
קהילות
לימודים
אינדקס
לאישה
דרושים
ynet-shops
ynettours
winwin
בעלי מקצוע
ביגדיל
+
+ +
 

אודות ועזרה
כתבו אלינו
עזרה
מדיניות פרטיות
תנאי שימוש
מפת האתר
ארכיון
מרכזי המבקרים
Israel News
 
אודות האתר
RSS
הפוך לדף הבית
ynet בסלולר
ניוזלטרים
פרסמו אצלנו
אנציקלופדיה
באבלס
ערוצי תוכן
חדשות
כלכלה
ספורט
תרבות
בריאות
מחשבים
נופש
Xnet
יהדות
דעות
צרכנות
תיירות
אוכל
רכב
בעלי חיים
קטלוג אופנה
יחסים
קהילות
אסטרולוגיה
מעורבות
ירוק
לאשה
דילים
ynetart
כלכליסט
בלייזר
Go
מנטה
משחקים
mynet
מפות
פרוגי
כלים ושירותים
קניות
מניות
דרושים
מחירון רכב
דירות להשכרה
קופונים
זיכרונט
דירות למכירה
לוח רכב
יד שניה
בעלי מקצוע
משחקים Games
עברית.evrit
דירות חדשות

YIT  - פיתוח אינטרנט ואפליקציותTotal media - Interactive media technologiesApplication delivery by radwarePowered by Akamaiהאתר פועל ברישיון אקו"םהאתר פועל ברישיון תל"י
as33-c  כל הזכויות שמורות לידיעות אינטרנט ©
+
+ + + + diff --git a/newsdiff/core/tests/content/4480544.html b/newsdiff/core/tests/content/4480544.html new file mode 100644 index 0000000..dcfc633 --- /dev/null +++ b/newsdiff/core/tests/content/4480544.html @@ -0,0 +1,965 @@ + + +ynet טרור בלב קהיר: 5 הרוגים, עשרות פצועים - חדשות + + + + + + + + + + + + + + + + +
הכי באזזזזז
    אולפן ynet
    צילום: עידו בקר, אורי דוידוביץ ואבי חי חם ויבש באמצע החורף - והטבע משתגעהבן תיעד התעללות מחרידה באמוצילום: ניצן דרורההורים שתקועים עם התינוקות בתאילנד
    טרור בלב קהיר: 5 הרוגים, עשרות פצועים
    מתקפת טרור בבירה המצרית. יום לפני יום השנה למהפכה שבה הודח הנשיא מובארק אירעו פיגוע תופת במינהלת הביטחון ועוד שני פיצוצים בבירה

    +

    לקראת ציון שלוש שנים למהפכה - פיגוע קטלני בלב מצרים + : מכונית תופת התפוצצה הבוקר (יום ו') בקהיר ודובר משרד הפנים המצרי דיווח שלפחות ארבעה בני אדם נהרגו וכ-51 נפצעו. הפיגוע התרחש סמוך למינהלת הביטחון באזור אל-עאבדין בבירה וככל הנראה בין הנפגעים גם אנשי ביטחון. מחר יצוין במצרים יום השנה השלישי למהפכת 25 בינואר שבה הודח חוסני מובארק.  +  

    +

     

    +

    צפו בעשן המיתמר לאחר הפיצוץ בבירה:

    +

    סגורסגור

    שליחה לחבר

     הקלידו את הקוד המוצג
    תמונה חדשה

    שלח
    הסרטון נשלח לחברך

    סגורסגור

    הטמעת הסרטון באתר שלך

     קוד להטמעה:

     

    +

    רויטרס

    זירת הפיגוע, הבוקר

    סגורסגור

    שליחה לחבר

     הקלידו את הקוד המוצג
    תמונה חדשה

    שלח
    הסרטון נשלח לחברך

    סגורסגור

    הטמעת הסרטון באתר שלך

     קוד להטמעה:

     

    +

    עשן במקום הפיצוץ בקהיר, מול מטה כוחות הביטחון ()
    עשן במקום הפיצוץ בקהיר, מול מטה כוחות הביטחון 

    +

     

    +

    העיתון "אל-יום א-סאבע" דיווח שלאחר הפיצוץ נשמעו יריות לכיווון מבנים באזור. עשן היתמר במרכז העיר. בנוסף נמסר שחזית הבניין קרסה ונזק רב נגרם גם בתוך הבניין. 

    +

    כמו כן, גרם הפיצוץ להרס רב במוזיאון האומנות האיסלאמית שנמצא מול מנהלת הביטחון, ובחנויות הסמוכות.

    +

     

    +

    כלי תקשורת במצרים דיווחו כי הארגון הקיצוני אנסאר בית אל-מקדס, המזוהה עם אל-קאעידה, קיבל על עצמו אחריות לפיגוע במנהלת הביטחון בקהיר. מדובר באותו ארגון שאתמול קיבל על עצמו אחריות לתקיפה הקטלנית של חמושים בדרום מצרים במחוז בני סווייף, שבה נהרגו חמישה שוטרים. מוקדם יותר השבוע קיבל אותו ארגון אחריות לירי הרקטות לעבר אילת.

    +

     

    +

    זמן קצר לאחר מכן דיווחו כלי תקשורת במצרים כי מטען נפץ מאולתר התפוצץ באזור א-דקי בעיר גיזה שליד קהיר, סמוך לתחנה של הרכבת התחתית. על פי הדיווחים, אדם אחד נהרג ו-15 נפצעו, בהם עשרה שוטרים. בעיתון "אל-יום א-סאבע" דווח כי הפיצוץ אירע ליד ארבעה רכבים של מנגנוני הביטחון המאבטחים את האזור, שצפויות להתקיים בו היום הפגנות של האחים המוסלמים.

    +

    +

      +

    פיצוץ שלישי מאז הבוקר נשמע סמוך לתחנת משטרה ליד הפירמידות בקהיר בירת מצרים. כך דיווחו גורמים רשמיים במדינה. בשלב זה לא ידוע על נפגעים. +

      +

    מוקדם יותר לפנות בוקר חשפו כוחות הביטחון המצריים מכונית תופת במחוז פורט סעיד וככל הנראה מנעו אסון כבד.

    +

    +

    +

     

    +

    הפיצוצים מתרחשים יום אחרי שחמישה שוטרים נהרגו במארב של חמושים בנקודת ביקורת במחוז בני סווייף. הארגון הסלפי הקיצוני "אנסאר בית אל-מקדס", שפועל בחצי האי סיני נגד הצבא, קיבל אחריות גם למארב אתמול.

    +

     

    +

    לקראת ציון שלוש שנים למהפכת 25 בינואר נמצאים מנגנוני הביטחון במצרים בכוננות שיא מחשש לפיגועים ולהפגנות שבהן יתעמתו תומכי האחים המוסלמים עם פעילי תנועות פוליטיות המזוהות עם המהפכה.

    +

     

    +

    בשבוע שעבר הודיעה ועדת הבחירות העליונה במצרים כי החוקה החדשה + עברה ברוב מוחץ של 98.1%. עשרים מיליון וחצי אזרחים הצביעו מתוך 52 מיליון בעלי זכות בחירה (38.6%). לשם השוואה, במשאל העם על החוקה לפני כשנה בעידן האחים המוסלמים יצאו להצביע רק 32.9%. החוקה הקודמת אושרה ברוב של 63.8 אחוזים. האחים המוסלמים החרימו את ההצבעה.

    +

     

    +

    Read this article in English

    +

      +

     

      קישורים ממומנים
       תגובה חדשה
      הצג:
      כל התגובות לכתבה טרור בלב קהיר: 5 הרוגים, עשרות פצועים
      אזהרה:
      פעולה זו תמחק את התגובה שהתחלת להקליד
      + +
      + \ No newline at end of file diff --git a/newsdiff/core/tests/haaretz_tests.py b/newsdiff/core/tests/haaretz_tests.py new file mode 100644 index 0000000..3c26e35 --- /dev/null +++ b/newsdiff/core/tests/haaretz_tests.py @@ -0,0 +1,44 @@ +from bs4 import BeautifulSoup +from django.test import TestCase +from unipath import FSPath as Path + +from newsdiff.core.parsers.haaretz import HaaretzParser +from ..models import HaaretzArticle, HaaretzImage + +class HaaretzParsingTestCase(TestCase): + + CONTENT_DIR = Path(__file__).absolute().parent.child('content') + + def setUp(self): + self.parser = HaaretzParser() + + def _get_content(self, filename): + with open(self.CONTENT_DIR.child(filename), 'r') as f: + return f.read() + + def _get_soup(self, filename): + return BeautifulSoup(self._get_content(filename), 'lxml') + + def test_parse_homepage(self): + soup = self._get_soup('homepage.html') + articles = self.parser.parse_homepage(soup) + self.assertEqual(len(articles), 67) + + def test_parse_article(self): + article_id = '1.2198200' + article_url = self.parser.article_id_to_url(article_id) + soup = self._get_soup('{}.html'.format(article_id)) + self.parser.parse_article(article_url, soup) + article = HaaretzArticle.objects.get(haaretz_id=article_id) + self.assertEqual(article.url, article_url) + images = article.images + self.assertEqual(images.count(), 2) + + def test_duplicate_article(self): + article_id = '1.2198200' + soup = self._get_soup('{}.html'.format(article_id)) + self.parser.parse_article(article_id, soup) + article = HaaretzArticle.objects.all() + self.assertEqual(article.count(), 1) + images = HaaretzImage.objects.all() + self.assertEqual(images.count(), 2) diff --git a/newsdiff/core/tests/tests.py b/newsdiff/core/tests/tests.py deleted file mode 100644 index b30b143..0000000 --- a/newsdiff/core/tests/tests.py +++ /dev/null @@ -1,44 +0,0 @@ -from bs4 import BeautifulSoup -from django.test import TestCase -from unipath import FSPath as Path - -from newsdiff.core.parsers.haaretz import HaaretzParser -from ..models import HaaretzArticle, HaaretzImage - -class HaaretzParsingTestCase(TestCase): - - CONTENT_DIR = Path(__file__).absolute().parent.child('content') - - def setUp(self): - self.parser = HaaretzParser() - - def _get_content(self, filename): - with open(self.CONTENT_DIR.child(filename), 'r') as f: - return f.read() - - def _get_soup(self, filename): - return BeautifulSoup(self._get_content(filename), 'lxml') - - def test_parse_homepage(self): - soup = self._get_soup('homepage.html') - articles = self.parser.parse_homepage(soup) - self.assertEqual(len(articles), 67) - - def test_parse_article(self): - article_id = '1.2198200' - article_url = '{}/{}'.format(self.parser.BASE_URL, article_id) - soup = self._get_soup('{}.html'.format(article_id)) - self.parser.parse_article(article_url, soup) - article = HaaretzArticle.objects.get(haaretz_id=article_id) - self.assertEqual(article.url, article_url) - images = article.images - self.assertEqual(images.count(), 2) - - def test_duplicate_article(self): - article_id = '1.2198200' - soup = self._get_soup('{}.html'.format(article_id)) - self.parser.parse_article(article_id, soup) - article = HaaretzArticle.objects.all() - self.assertEqual(article.count(), 1) - images = HaaretzImage.objects.all() - self.assertEqual(images.count(), 2) diff --git a/newsdiff/core/tests/ynet_tests.py b/newsdiff/core/tests/ynet_tests.py new file mode 100644 index 0000000..1798190 --- /dev/null +++ b/newsdiff/core/tests/ynet_tests.py @@ -0,0 +1,35 @@ +from bs4 import BeautifulSoup +from django.test import TestCase +from unipath import FSPath as Path + +from newsdiff.core.parsers.ynet import YnetParser +from ..models import YnetArticle, YnetImage + +class YnetParsingTestCase(TestCase): + + CONTENT_DIR = Path(__file__).absolute().parent.child('content') + + def setUp(self): + self.parser = YnetParser() + + def _get_content(self, filename): + with open(self.CONTENT_DIR.child(filename), 'r') as f: + return f.read() + + def _get_soup(self, filename): + return BeautifulSoup(self._get_content(filename), 'lxml') + + def test_parse_homepage(self): + soup = self._get_soup('0,7340,L-2,00.html') + articles = self.parser.parse_homepage(soup) + self.assertEqual(len(articles), 49) + + def test_parse_article(self): + article_id = '4480544' + article_url = self.parser.article_id_to_url(article_id) + soup = self._get_soup('{}.html'.format(article_id)) + self.parser.parse_article(article_url, soup) + article = YnetArticle.objects.get(ynet_id=article_id) + self.assertEqual(article.url, article_url) + images = article.images + self.assertEqual(images.count(), 0) \ No newline at end of file diff --git a/newsdiff/settings/base.py b/newsdiff/settings/base.py index 6c3f7ad..4e3d75d 100644 --- a/newsdiff/settings/base.py +++ b/newsdiff/settings/base.py @@ -135,5 +135,9 @@ CELERYBEAT_SCHEDULE = { 'haaretz_homepage': { 'task': 'newsdiff.core.tasks.process_haaretz_homepage', 'schedule': timedelta(minutes=15) + }, + 'ynet_homepage': { + 'task': 'newsdiff.core.tasks.process_ynet_homepage', + 'schedule': timedelta(minutes=15) } } -- cgit v1.3.1