parser.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #!/usr/bin/python3
  2. import sys
  3. import re
  4. import newspaper
  5. import pymongo
  6. import htmlmin
  7. import feedparser
  8. import datetime
  9. from frontpage import FrontPage
  10. from newspaper import Article
  11. from db import db
  12. from source import Source
  13. class LinkList():
  14. def __init__(self,url,selector=None,rss=False):
  15. self.links=[]
  16. if rss:
  17. feed = feedparser.parse(url)
  18. #print(feed["bozo"]) FIXME: If bozo==1 => error
  19. self.links=[i["link"] for i in feed["items"]]
  20. print(self.links)
  21. else:
  22. if selector is None:
  23. #s=newspaper.build(url,language="en",memoize_articles=False) #memoize puede salvarme la vida
  24. s = newspaper.Source(url,memoize_articles=False)
  25. s.download()
  26. s.parse()
  27. s.set_categories()
  28. s.download_categories()
  29. s.parse_categories()
  30. s.generate_articles()
  31. self.links=list(set([a.url for a in s.articles])) #avoid dupes
  32. else:
  33. f=FrontPage(url,selector)
  34. self.links=f.links
  35. self.links=self.purgeLinks(self.links)
  36. def purgeLinks(self,l):
  37. return [ sanitizeUrl(link) for link in l if not "presslist" in link.lower() and not "videolist" in link.lower() ]
  38. class News():
  39. r=re.compile(r"hours? ago|yesterday|today|last week|month",flags=re.IGNORECASE)
  40. r_noise=re.compile(r"posted|Product|Google",flags=re.IGNORECASE)
  41. URL=""
  42. AUTHORS=[]
  43. SCRAP_DATE=None
  44. PUBLISH_DATE=None
  45. SUMMARY=""
  46. TEXT=""
  47. HTML=""
  48. ERROR=False
  49. SOURCE=""
  50. def __init__(self,url,source,lang="en"):
  51. url=sanitizeUrl(url)
  52. self.URL=url
  53. self.SOURCE=source
  54. a = Article(url, language=lang,keep_article_html=True)
  55. a.download()
  56. a.parse()
  57. a.nlp()
  58. a.authors=self.dedup([self.fix_author(value) for value in a.authors if not self.isComment(value) and not self.isNoise(value)])
  59. self.SCRAP_DATE=datetime.datetime.now()
  60. self.AUTHORS=a.authors
  61. self.PUBLISH_DATE=a.publish_date
  62. self.SUMMARY=a.summary
  63. self.TEXT=a.text
  64. self.HTML=htmlmin.minify(a.article_html,remove_empty_space=True)
  65. def get(self):
  66. return {
  67. "url": self.URL,
  68. "source": self.SOURCE,
  69. "authors": self.AUTHORS,
  70. "scrap_date": self.SCRAP_DATE,
  71. "publish_date": self.PUBLISH_DATE,
  72. "summary": self.SUMMARY,
  73. "text": self.TEXT,
  74. "html": self.HTML
  75. }
  76. def dedup(self,val):
  77. return list(set(val))
  78. def isNoise(self,v):
  79. if self.r_noise.match(v):
  80. return True
  81. return False
  82. def isComment(self,v):
  83. if self.r.match(v):
  84. return True
  85. return False
  86. def fix_author(self,a):
  87. return a.replace("_", " ").lower()
  88. unsharer=re.compile(r"(\?share=|#).+$",flags=re.IGNORECASE)
  89. def sanitizeUrl(url):
  90. global unsharer
  91. ret = re.sub(unsharer, "",url)
  92. return ret
  93. def sanitizeSelector(s):
  94. s=s.replace(">a","> a")
  95. if re.match(r'=\w+\]',s) is None:
  96. return s
  97. ret=re.sub(r"=(\w+)]", r'="\1"]', s)
  98. return ret
  99. d=db()
  100. for s in d.sources():
  101. print(s["name"])
  102. sel=None
  103. rss=False
  104. if "selector" in s:
  105. sel=s["selector"]
  106. if "rss" in s:
  107. rss=bool(["rss"])
  108. l=LinkList(s["link"],sel,rss=rss)
  109. if l is not None:
  110. for a in l.links:
  111. if not d.article_exists(a):
  112. print(a)
  113. n=News(a,s["_id"])
  114. d.insert_article(n.get())
  115. print(len(l.links))
  116. break