update

parent b3970bbd
#!/usr/bin/python3 #!/usr/bin/python3
# -*- coding: utf-8 -*- #Author: Mario Chirinos Colunga
#===============================================================================
import sys import sys
import os
from pathlib import Path from pathlib import Path
import datetime import datetime
#from myModule import myModule import json
#=============================================================================== #===============================================================================
def findLastDate(directory): def findLastDate(directory):
print(directory)
path = Path(directory) path = Path(directory)
dirs = [e.name for e in path.iterdir() if e.is_dir()] dirs = [e.name for e in path.iterdir() if e.is_dir()]
if len(dirs)>0:
dirs.sort() dirs.sort()
path = Path(directory+dirs[-1]) i = -1
while (len(dirs)+1)>=0:
path = Path(directory+dirs[i])
files = [e.name[:-5] for e in path.glob("*.json")] files = [e.name[:-5] for e in path.glob("*.json")]
if len(files)>0:
files.sort() files.sort()
date = datetime.datetime.strptime(files[-1], '%Y-%m-%d') date = datetime.datetime.strptime(files[-1], '%Y-%m-%d')
return date return date
i-=1
return None
#=============================================================================== #===============================================================================
def updateDir(directory): def updateDir(directory, cfg, endDate=datetime.datetime.now()):
startDate = findLastDate(directory) startDate = findLastDate(directory)
endDate = datetime.datetime.now() print(startDate, endDate)
# endDate = datetime.datetime.now()
if startDate is None:
startDate=datetime.datetime.strptime(cfg["startDate"], '%Y-%m-%d')
delta = endDate-startDate delta = endDate-startDate
for i in range(delta.days + 1): for i in range(delta.days + 1):
day = startDate + datetime.timedelta(days=i) day = startDate + datetime.timedelta(days=i)
yeardir = directory+str(day.year)+"/"
if not os.path.exists(yeardir):
os.mkdir(yeardir)
print(day) print(day)
os.system("scrapy crawl noticias --nolog -O "+yeardir+day.strftime('%Y-%m-%d')+".json -a year="+str(day.year)+" -a month="+str(day.month)+" -a day="+str(day.day)+"")
#=============================================================================== #===============================================================================
def main(argv): def main(argv):
if len(sys.argv) != 2: if len(argv) != 2 and len(argv) != 3:
print ("Usage text") print ("Usage: " + argv[0] + "<directory> [endDate:YYYY-MM-DD]")
else: else:
updateDir(argv[1]) with open(argv[1]+'settings.json') as json_file:
cfg = json.load(json_file)
if len(argv)==2:
updateDir(argv[1], cfg)
if len(argv)==3:
updateDir(argv[1], cfg, datetime.datetime.strptime(argv[2], '%Y-%m-%d'))
if __name__ == "__main__": if __name__ == "__main__":
main(sys.argv) main(sys.argv)
#!/usr/bin/python3
import sys
import os
import json
from pathlib import Path
import chardet
#from myModule import myModule
#===============================================================================
def ascii2utf8(inputfilename, outputfilename):
print(inputfilename)
with open(inputfilename) as json_file:
data = json.load(json_file)#.read().decode("unicode_escape")
print(data)
with open(outputfilename, 'w') as outfile:
json.dump(data, outfile, ensure_ascii=False, indent=1)
#===============================================================================
def copyDirStructure(indir, outdir):
print(indir)
path = Path(indir)
dirs = [e.name for e in path.iterdir() if e.is_dir()]
if not os.path.exists(outdir+path.name):
os.mkdir(outdir+path.name)
for d in dirs:
yeardir = outdir+path.name+"/"+d+"/"
print(path.name, d)
if not os.path.exists(yeardir):
os.mkdir(yeardir)
filepath = Path(indir+d)
files = [e.name for e in filepath.glob("*.json")]
for f in files:
ascii2utf8(indir+d+"/"+f, yeardir+f)
#===============================================================================
def main(argv):
if len(sys.argv) != 3:
print ("Usage: " + argv[0] + " <input dir> <output dir>")
else:
copyDirStructure(argv[1], argv[2])
if __name__ == "__main__":
main(sys.argv)
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class NoticiasItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
text = scrapy.Field()
date = scrapy.Field()
location = scrapy.Field()
author = scrapy.Field()
topic = scrapy.Field()
url = scrapy.Field()
# -*- coding: utf-8 -*-
# Define here the models for your spider middleware
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/spider-middleware.html
from scrapy import signals
class AlchileSpiderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the spider middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_spider_input(response, spider):
# Called for each response that goes through the spider
# middleware and into the spider.
# Should return None or raise an exception.
return None
def process_spider_output(response, result, spider):
# Called with the results returned from the Spider, after
# it has processed the response.
# Must return an iterable of Request, dict or Item objects.
for i in result:
yield i
def process_spider_exception(response, exception, spider):
# Called when a spider or process_spider_input() method
# (from other spider middleware) raises an exception.
# Should return either None or an iterable of Response, dict
# or Item objects.
pass
def process_start_requests(start_requests, spider):
# Called with the start requests of the spider, and works
# similarly to the process_spider_output() method, except
# that it doesn’t have a response associated.
# Must return only requests (not items).
for r in start_requests:
yield r
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
import json
from collections import OrderedDict
class JsonWriterPipeline(object):
def __init__(self, filename):
self.filename = filename
@classmethod
def from_crawler(cls, crawler):
# Here you get whatever value was passed through the "filename" command line parameter
settings = crawler.settings
filename = settings.get('filename')
# Instantiate the pipeline with the file name
return cls(filename)
def open_spider(self, spider):
self.counter = 0
self.file = open(self.filename, 'w')
self.file.write("[")
def close_spider(self, spider):
self.file.write("]")
self.file.close()
def process_item(self, item, spider):
# print("this is my item", item)
row = []
try:
row.append(("date", item['date']))
except:
pass
try:
row.append(("topic", item['topic']))
except:
pass
try:
row.append(("title", item['title']))
except:
pass
try:
row.append(("author", item['author']))
except:
pass
try:
row.append(("location", item['location']))
except:
pass
try:
row.append(("text", item['text']))
except:
pass
try:
row.append(("url", item['url']))
except:
pass
line = OrderedDict(row)
self.counter += 1
if self.counter == 1:
self.file.write(json.dumps(line))
elif self.counter > 1:
self.file.write(",\n" + json.dumps(line))
return item
# -*- coding: utf-8 -*-
# Scrapy settings for alChile project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
# http://doc.scrapy.org/en/latest/topics/settings.html
# http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
# http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html
BOT_NAME = 'alChile'
SPIDER_MODULES = ['alChile.spiders']
NEWSPIDER_MODULE = 'alChile.spiders'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'alChile (+http://www.yourdomain.com)'
# Obey robots.txt rules
# ROBOTSTXT_OBEY = True
# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32
# Configure a delay for requests for the same website (default: 0)
# See http://scrapy.readthedocs.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.5
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16
# Disable cookies (enabled by default)
COOKIES_ENABLED = False
# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False
# Override the default request headers:
#DEFAULT_REQUEST_HEADERS = {
# 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
# 'Accept-Language': 'en',
#}
# Enable or disable spider middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
# 'alChile.middlewares.AlchileSpiderMiddleware': 543,
#}
# Enable or disable downloader middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
# 'alChile.middlewares.MyCustomDownloaderMiddleware': 543,
#}
# Enable or disable extensions
# See http://scrapy.readthedocs.org/en/latest/topics/extensions.html
#EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None,
#}
# Configure item pipelines
# See http://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'alChile.pipelines.JsonWriterPipeline': 300,
}
# Enable and configure the AutoThrottle extension (disabled by default)
# See http://doc.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True
# The initial download delay
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False
# Enable and configure HTTP caching (disabled by default)
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
# This package will contain the spiders of your Scrapy project
#
# Please refer to the documentation for information on how to create and manage
# your spiders.
# -*- coding: utf-8 -*-
import scrapy, re
from alChile.items import NoticiasItem
"""
MEDIO:
Al Chile, Yucatan
USO:
scrapy crawl noticias --nolog -s filename=2017-03-22.json -a year=2017 -a month=3 -a day=22
"""
TAG_RE = re.compile(r'<[^>]+>')
def remove_tags(text):
return TAG_RE.sub('', text)
class QuotesSpider(scrapy.Spider):
name = "noticias"
def start_requests(self):
year = getattr(self, 'year', None)
month = getattr(self, 'month', None)
day = getattr(self, 'day', None)
self.baseURL = 'http://alchile.com.mx/' + year + '/' + month + '/' + day
yield scrapy.Request(url=self.baseURL, callback=self.parse)
def parse(self, response):
yield scrapy.Request(url=response.url, callback=self.parse_page, dont_filter=True)
pagination = response.css('div.page-nav').css('a::attr(href)').extract()
if len(pagination) > 0:
pagination = pagination[-2].strip('/')
pages = int(pagination[pagination.rfind('/')+1:])
for page in range(1,pages):
yield scrapy.Request(url=self.baseURL+"/page/"+str(page+1), callback=self.parse_page)
def parse_page(self, response):
for link in response.css('div.td-block-span6').css('h3.entry-title').css('a::attr(href)').extract():
yield scrapy.Request(url=link, callback=self.parse_item)
def parse_item(self, response):
item = NoticiasItem()
text = ''
item['title'] = response.css('header.td-post-title').css('h1.entry-title::text').extract_first()
d = response.css('span.td-post-date').css('time.entry-date::attr(datetime)').extract_first()
## '-06:00' corresponde al UTC-6, zona horaria de yucatan (centro de mexico)
if d[-6:] != '-06:00':
d = d[:-6] + '-06:00'
item['date'] = d
item['topic'] = response.css('div.td-post-header').css('a::text').extract_first()
for paragraph in response.css('div.td-post-content').css('p').extract():
text += remove_tags(paragraph) + '\n'
item['text'] = text
item['url'] = response.url
# print item['title']
yield item
# Automatically created by: scrapy startproject
#
# For more information about the [deploy] section see:
# https://scrapyd.readthedocs.org/en/latest/deploy.html
[settings]
default = alChile.settings
[deploy]
#url = http://localhost:6800/
project = alChile
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class NoticiasItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
text = scrapy.Field()
date = scrapy.Field()
location = scrapy.Field()
author = scrapy.Field()
topic = scrapy.Field()
url = scrapy.Field()
# -*- coding: utf-8 -*-
# Define here the models for your spider middleware
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/spider-middleware.html
from scrapy import signals
class CampechehoySpiderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the spider middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_spider_input(response, spider):
# Called for each response that goes through the spider
# middleware and into the spider.
# Should return None or raise an exception.
return None
def process_spider_output(response, result, spider):
# Called with the results returned from the Spider, after
# it has processed the response.
# Must return an iterable of Request, dict or Item objects.
for i in result:
yield i
def process_spider_exception(response, exception, spider):
# Called when a spider or process_spider_input() method
# (from other spider middleware) raises an exception.
# Should return either None or an iterable of Response, dict
# or Item objects.
pass
def process_start_requests(start_requests, spider):
# Called with the start requests of the spider, and works
# similarly to the process_spider_output() method, except
# that it doesn’t have a response associated.
# Must return only requests (not items).
for r in start_requests:
yield r
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
import json
from collections import OrderedDict
class JsonWriterPipeline(object):
def __init__(self, filename):
self.filename = filename
@classmethod
def from_crawler(cls, crawler):
# Here you get whatever value was passed through the "filename" command line parameter
settings = crawler.settings
filename = settings.get('filename')
# Instantiate the pipeline with the file name
return cls(filename)
def open_spider(self, spider):
self.counter = 0
self.file = open(self.filename, 'w')
self.file.write("[")
def close_spider(self, spider):
self.file.write("]")
self.file.close()
def process_item(self, item, spider):
# print("this is my item", item)
row = []
try:
row.append(("date", item['date']))
except:
pass
try:
row.append(("topic", item['topic']))
except:
pass
try:
row.append(("title", item['title']))
except:
pass
try:
row.append(("author", item['author']))
except:
pass
try:
row.append(("location", item['location']))
except:
pass
try:
row.append(("text", item['text']))
except:
pass
try:
row.append(("url", item['url']))
except:
pass
line = OrderedDict(row)
self.counter += 1
if self.counter == 1:
self.file.write(json.dumps(line))
elif self.counter > 1:
self.file.write(",\n" + json.dumps(line))
return item
# -*- coding: utf-8 -*-
# Scrapy settings for campecheHoy project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
# http://doc.scrapy.org/en/latest/topics/settings.html
# http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
# http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html
BOT_NAME = 'campecheHoy'
SPIDER_MODULES = ['campecheHoy.spiders']
NEWSPIDER_MODULE = 'campecheHoy.spiders'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'campecheHoy (+http://www.yourdomain.com)'
# Obey robots.txt rules
# ROBOTSTXT_OBEY = True
# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32
# Configure a delay for requests for the same website (default: 0)
# See http://scrapy.readthedocs.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.5
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16
# Disable cookies (enabled by default)
COOKIES_ENABLED = False
# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False
# Override the default request headers:
#DEFAULT_REQUEST_HEADERS = {
# 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
# 'Accept-Language': 'en',
#}
# Enable or disable spider middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
# 'campecheHoy.middlewares.CampechehoySpiderMiddleware': 543,
#}
# Enable or disable downloader middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
# 'campecheHoy.middlewares.MyCustomDownloaderMiddleware': 543,
#}
# Enable or disable extensions
# See http://scrapy.readthedocs.org/en/latest/topics/extensions.html
#EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None,
#}
# Configure item pipelines
# See http://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'campecheHoy.pipelines.JsonWriterPipeline': 300,
}
# Enable and configure the AutoThrottle extension (disabled by default)
# See http://doc.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True
# The initial download delay
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False
# Enable and configure HTTP caching (disabled by default)
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
# This package will contain the spiders of your Scrapy project
#
# Please refer to the documentation for information on how to create and manage
# your spiders.
# -*- coding: utf-8 -*-
import scrapy, re
from campecheHoy.items import NoticiasItem
"""
MEDIO:
Campeche Hoy, Campeche
USO:
scrapy crawl noticias --nolog -s filename=2018-01-17.json -a year=2018 -a month=1 -a day=17
"""
TAG_RE = re.compile(r'<[^>]+>')
def remove_tags(text):
return TAG_RE.sub('', text)
class QuotesSpider(scrapy.Spider):
name = "noticias"
def start_requests(self):
year = getattr(self, "year", None)
month = getattr(self, "month", None)
day = getattr(self, "day", None)
self.baseURL = "http://campechehoy.mx/" + year + "/" + month + "/" + day
yield scrapy.Request(url=self.baseURL, callback=self.parse)
def parse(self, response):
yield scrapy.Request(url=response.url, callback=self.parse_page, dont_filter=True)
pagination = response.xpath('//*[@class="page-nav td-pb-padding-side"]/a/@href').extract()
if pagination is not None and len(pagination) > 0:
pages = pagination[-2].rstrip("/")
pages = int(pages[pages.rfind("/")+1:])
for page in range(1, pages):
yield scrapy.Request(url=self.baseURL+"/page/"+str(page+1), callback=self.parse_page)
def parse_page(self, response):
for link in response.xpath('//*[@class="td-pb-span8 td-main-content"]').css('h3').css('a::attr(href)').extract():
yield scrapy.Request(url=link, callback=self.parse_item)
def parse_item(self, response):
item = NoticiasItem()
text = ''
"La fecha obtenida ya incluye formato y zona horaria"
item['date'] = response.xpath('//span[@class="td-post-date"]/time/@datetime').extract_first()
item['title'] = remove_tags(response.xpath('//header/h1[@class="entry-title"]').extract_first())
try:
topic = response.xpath('//*[@class="td-post-source-tags td-pb-padding-side"]/ul/li/a/text()').extract()[1]
except:
topic = response.xpath('//*[@class="td-post-source-tags td-pb-padding-side"]/ul/li/a/text()').extract_first()
item['topic'] = topic
for p in response.xpath('//*[@class="td-post-content td-pb-padding-side"]/p').extract():
p = remove_tags(p)
p = p.replace("&lt;", "<")
p = p.replace("&gt;", ">")
text += remove_tags(p) + "\n"
item['text'] = text
item['url'] = response.url
yield item
# Automatically created by: scrapy startproject
#
# For more information about the [deploy] section see:
# https://scrapyd.readthedocs.org/en/latest/deploy.html
[settings]
default = campecheHoy.settings
[deploy]
#url = http://localhost:6800/
project = campecheHoy
[{"date": "2019/09/17", "topic": "Municipios", "title": "En Cintalapa, se Conmemora el CCIX aniversario de la Independencia de M\u00e9xico", "author": "Chiapas Hoy//MdR", "text": "Cintalapa de Figueroa, Chiapas. \u2013 Con el objetivo de recordar fechas importantes de la historia de M\u00e9xico, el Alcalde Lic. Jos\u00e9 Francisco Nava Clemente y el Coronel del 100 batall\u00f3n de infanter\u00eda, Argel Mendoza Cort\u00e9s, encabezaron el desfile c\u00edvico militar, conmemorativo al 209 aniversario del inicio de la Independencia de nuestro pa\u00eds.\nCon gran algarab\u00eda, los ciudadanos disfrutaron de este recorrido, que abarc\u00f3 del parque de Guadalupe a la explanada central, donde integrantes del ej\u00e9rcito militar marcharon frente a los asistentes, para conmemorar la entrada del Ej\u00e9rcito.Estuvieron acompa\u00f1ados de diferentes corporaciones que brinda atenci\u00f3n en caso de emergencias, as\u00ed como de escuadrones y camiones de trabajo. En este acto, tambi\u00e9n participaron instituciones educativas.\u201cFomentamos historia, valores y sobre todo amor a nuestras ra\u00edces, es de importancia recordar estas an\u00e9cdotas como mexicanos que somos; agradezco intenso apoyo que nos ha brindado el 100 batall\u00f3n para ejecutar estas actividades\u201d puntualiz\u00f3 el edil.Nava Clemente hizo entrega de un reconocimiento al Coronel Mendoza Cort\u00e9s, por el apoyo brindado en estos festejos y por el apoyo en materia de seguridad.Estuvieron presentes integrantes del H. Cabildo, directores de \u00e1reas, instituciones educativas y p\u00fablico en general.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/estados/en-cintalapa-se-conmemora-el-ccix-aniversario-de-la-independencia-de-mexico/"},
{"date": "2019/09/17", "topic": "ChiapasHoy", "title": "Aporta UNICACH a difusi\u00f3n de la ciencia en lenguas ind\u00edgenas", "author": "Chiapas Hoy//MdR", "text": "Rector Jos\u00e9 Rodolfo Calvo Fonseca clausur\u00f3 actividades del taller\nEl rector de la UNICACH, Jos\u00e9 Rodolfo Calvo Fonseca clausur\u00f3 las actividades del \u201cIV Taller de Producci\u00f3n Radif\u00f3nica en Lenguas Ind\u00edgenas\u201d, organizado por la Radio UNICACH 102.5 F. M en coordinaci\u00f3n con la Sociedad Mexicana para la Divulgaci\u00f3n de la Ciencia y la T\u00e9cnica, A.C. (SOMEDICyT) y el Consejo Nacional de Ciencia y Tecnolog\u00eda (Conacyt).\nAl finalizar las actividades, el rector Calvo Fonseca entreg\u00f3 constancias a los 30 comunicadores y 14 traductores del centro, norte y sur del pa\u00eds, que fueron capacitados por Cristopher Escamilla Arrieta, productor radiof\u00f3nico de la Universidad Aut\u00f3noma de M\u00e9xico (UNAM).\nEn total se produjeron 24 capsulas radiof\u00f3nicas en 8 lenguas ind\u00edgenas, tales como tsotsil, tseltal, pur\u00e9pecha, yaqui seri, zoque, chol y espa\u00f1ol, con ello se da continuidad al proyecto de divulgaci\u00f3n cient\u00edfica SurCiencia, coproducido por la radio unicachense y la SOMEDICyT.\nAnte Libia Elena Barajas Mariscal, coordinadora acad\u00e9mica y log\u00edstica del taller y Roberto Lorenzo Rueda, director general de Culturas Populares y Urbanas de Chiapas, el rector de la UNICACH agradeci\u00f3 la confianza depositada en la Radio UNICACH 102.5 FM como sede de este importante evento acad\u00e9mico.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/chiapashoy/aporta-unicach-a-difusion-de-la-ciencia-en-lenguas-indigenas/"},
{"date": "2019/09/17", "topic": "ChiapasHoy", "title": "Encabeza Rutilio Escand\u00f3n desfile c\u00edvico-militar por el 209 aniversario de la Independencia de M\u00e9xico", "author": "Chiapas Hoy//MdR", "text": "\u2022 Participaron elementos de las Fuerzas Armadas, Polic\u00edas estatales, instituciones educativas y civiles, asociaciones de charros, entre otros\n\u2022 Se destac\u00f3 la presencia de la Guardia Nacional, que por primera vez desfil\u00f3 ante el pueblo como parte del contingente de seguridad\nJunto a cientos de familias que se congregaron a lo largo de la Avenida Central de la capital chiapaneca, el gobernador Rutilio Escand\u00f3n Cadenas presenci\u00f3 el desfile c\u00edvico-militar con motivo del 209 aniversario del inicio de la Independencia de M\u00e9xico, el cual se llev\u00f3 a cabo en total orden y concluy\u00f3 con saldo blanco.Acompa\u00f1ado de los comandantes de la S\u00e9ptima Regi\u00f3n Militar, Juan Ernesto Antonio Bernal Reyes, y de la 14 Zona Naval con sede en Puerto Chiapas, Rafael Adolfo Su\u00e1rez Gonz\u00e1lez, el jefe del Ejecutivo estatal observ\u00f3 los distintos contingentes participantes, que, desde sus trincheras, han demostrado compromiso, disciplina, honestidad, lealtad, orgullo y pasi\u00f3n de servir a M\u00e9xico y a Chiapas.Tras atender el saludo de las fuerzas militares, el mandatario mostr\u00f3 su benepl\u00e1cito por la participaci\u00f3n de la Guardia Nacional, que por primera vez desfil\u00f3 ante el pueblo de Chiapas como un cuerpo de seguridad p\u00fablica de car\u00e1cter civil, constituido por personal militar, naval y Polic\u00eda Federal; mujeres y hombres dispuestos a cumplir su misi\u00f3n y encomienda.En ese tenor, constat\u00f3 el equipamiento y uso de tecnolog\u00edas para el mejor desempe\u00f1o de las Fuerzas Armadas y polic\u00edas estatales, adem\u00e1s de reconocer la plena coordinaci\u00f3n y comunicaci\u00f3n interinstitucional que han permitido garantizar el respeto de los derechos humanos, as\u00ed como la seguridad y bienestar de las familias que habitan en las distintas regiones del estado.Al dar a conocer el parte de novedades, el comandante de la Columna del Desfile, Aristeo Taboada Rivera, precis\u00f3 que participaron: 11 banderas de guerra, mil 500 elementos de las tres Fuerzas Armadas, 280 de la Guardia Nacional, 876 de diferentes cuerpos de seguridad p\u00fablica y protecci\u00f3n ciudadana, 955 integrantes de planteles educativos e instituciones civiles, 40 charros, nueve aeronaves, 158 veh\u00edculos, 33 motocicletas, siete canes y 76 caballos.\nCabe mencionar que en esta parada c\u00edvico militar, donde las Fuerzas Armadas de M\u00e9xico reiteraron su lealtad y compromiso, destac\u00f3 el contingente para representar las tres primeras transformaciones del pa\u00eds con los carros aleg\u00f3ricos de la Independencia de M\u00e9xico, la Reforma y la Revoluci\u00f3n Mexicana, para dar paso al agrupamiento llamado Cuarta Transformaci\u00f3n, con los carros tem\u00e1ticos de los programas \u201cSembrando Vida\u201d y \u201cJ\u00f3venes Construyendo el Futuro\u201d, y a la Escuela Militarizada \u201c\u00c1ngel Albino Corzo\u201d.\nPreviamente, desde la Plaza Central de esta ciudad, Escand\u00f3n Cadenas encabez\u00f3 el Izado a toda asta de la Bandera Nacional con motivo de esta fecha conmemorativa, en la que estuvo presente el general Roberto Garc\u00eda Brenis, en representaci\u00f3n del comandante de la S\u00e9ptima Regi\u00f3n Militar y el contralmirante Camerino Roa Vidal, representante de la 14 Zona Naval con sede en Puerto Chiapas.\nEn ambos actos c\u00edvicos, estuvieron presentes los titulares de los poderes Legislativo, la diputada Rosa Elizabeth Bonilla Hidalgo y Judicial, Juan \u00d3scar Trinidad Palacios; as\u00ed como el fiscal general del Estado, Jorge Luis Llaven Abarca; el secretario general de Gobierno, Ismael Brito Mazariegos; la secretaria de Seguridad y Protecci\u00f3n Ciudadana, Gabriela Zepeda Soto; el presidente municipal de Tuxtla Guti\u00e9rrez, Carlos Morales V\u00e1zquez, entre otros servidores p\u00fablicos estatales, diputadas y diputados locales.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/chiapashoy/encabeza-rutilio-escandon-desfile-civico-militar-por-el-209-aniversario-de-la-independencia-de-mexico/"},
{"date": "2019/09/17", "topic": "Municipios", "title": "Asaltan Oxxo de P\u00e9rez Herrera en Tapachula", "author": "Fuente: ATN", "text": "Tapachula, Chiapas. Un sujeto que portaba una pistola, ingre\u00f3o a la tienda Oxxo que se ubica en la bajada de P\u00e9rez Herrera y octava Avenida norte, de la Colonia 5 de febrero.Sobre los hechos la cajera de nombre Daisy N., explic\u00f3 a los polic\u00edas que un sujeto la amago con una pistola, vest\u00eda playera Blanca, pantal\u00f3n azul y una mochila verde.El delincuente la despoj\u00f3 de la cantidad de 200 pesos, que ten\u00eda de cambio debido a que el dinero ya estaba en la caja fuerte.El delincuente al ver que no hab\u00eda m\u00e1s dinero, sali\u00f3 corriendo y se dio a la fuga; elementos de la Polic\u00eda Municipal arribaron al lugar, montaron un operativo sin que se lograr\u00e1 la detenci\u00f3n del presunto delincuente.\nFuente: ATN", "url": "http://www.chiapashoy.com.mx/notashoy/estados/asaltan-oxxo-de-perez-herrera-en-tapachula/"},
{"date": "2019/09/17", "topic": "TuxtlaHoy", "title": "Roban a negocio y se llevan bater\u00edas y dinero en efectivo", "author": "Fuente: V\u00f3rticeMX", "text": "Tuxtla Guti\u00e9rrez, Chiapas. \u2013 Luego de forzar una de las ventanas del negocio \u201cLa Casa de las Bater\u00edas\u201d, un grupo de amantes de lo ajeno, sustrajo 15 bater\u00edas y dinero en efectivo, sobre la 5\u00aa Norte y Calle Central.\nElementos de la Polic\u00eda Municipal y Estatal Preventiva arribaron al citado punto y ah\u00ed informaron que, se hab\u00eda registrado un robo a comercio.Estos se\u00f1alaron que, durante la madrugada, un grupo de malhechores forz\u00f3 una de las ventanas del citado inmueble y por ah\u00ed ingresaron para sustraer, 15 bater\u00edas, dos volt\u00edmetros y 2 mil pesos en efectivo.\nTras cometer sus fechor\u00edas, los delincuentes huyeron a bordo de un veh\u00edculo y con direcci\u00f3n hasta el momento desconocida.Al arribar los due\u00f1os para llevar a cabo sus labores, observaron lo sucedido y dieron aviso a las fuerzas de seguridad quienes arribaron para tomar datos de lo sucedido y posteriormente retirarse de la escena.\nFuente: V\u00f3rticeMX", "url": "http://www.chiapashoy.com.mx/notashoy/tuxtlahoy/roban-a-negocio-y-se-llevan-baterias-y-dinero-en-efectivo/"},
{"date": "2019/09/17", "topic": "M\u00e9xicoHoy", "title": "Deportistas orgullosos de ser mexicanos", "author": "Fuente: Agencias", "text": "El orgullo de representar a M\u00e9xico en el extranjero se extendi\u00f3 al Desfile C\u00edvico Militar que conmemora el inicio del Movimiento de Independencia.\nEl clavadista Rommel Pacheco celebr\u00f3 este lunes 10 a\u00f1os de pertenecer al Ej\u00e9rcito Mexicano. \u201cTienes m\u00e1s responsabilidad con el pa\u00eds y con la instituci\u00f3n, pero es muy bonito; me gustar\u00eda que la gente se sienta orgullosa del Ej\u00e9rcito, que cada d\u00eda se prepara para cuidarnos de cualquier situaci\u00f3n que la pudiera vivir la poblaci\u00f3n\u201d, dijo Pacheco Marrufo, quien es teniente.La subcampeona panamericana Jessica Sobrino tambi\u00e9n expres\u00f3 su orgullo. \u201cTengo familia que forma parte de la Secretar\u00eda de Marina; siempre me gust\u00f3; adem\u00e1s tenemos valores muy parecidos: en la instituci\u00f3n y c\u00f3mo deportistas lo que m\u00e1s deseamos es que M\u00e9xico muestre lo mejor; hay mucho trabajo, muchas exigencias; debemos apreciarlo\u201d, comparti\u00f3 la cabo en la Semar.Para la esgrimista, medallista continental, Nataly Michel, es una oportunidad de estar cerca de la gente. \u201cEs muy bonito desde que antes de salir, todos te saludan y te felicitan; es un gran compromiso formar parte de la Secretar\u00eda de Marina y lo mucho que comprendemos el orgullo de portar este uniforme\u201d, agreg\u00f3 la cabo de esta dependencia.Fernando Mart\u00ednez, Campe\u00f3n Panamericano, suma tres a\u00f1os en la Secretar\u00eda de la Defensa Nacional y es hoy sargento segundo. \u201cSe siente uno muy orgulloso, m\u00e1s porque reconozcan tus logros y tu trabajo\u201d, expres\u00f3 el corredor.El clavadista Yahel Castillo fue de las primeras generaciones que se incorpor\u00f3 a la Sedena y este a\u00f1o fue convocado a desfilar, pues sobre su pecho cuelgan medallas de Lima 2019.\u201cAs\u00ed como un militar hace brillar a Mexico, esa es la misi\u00f3n de cada deportista, representar al pa\u00eds dignamente\u201d, expres\u00f3 Castillo.\nFuente: Agencias", "url": "http://www.chiapashoy.com.mx/notashoy/mexicohoy/deportistas-orgullosos-de-ser-mexicanos/"},
{"date": "2019/09/17", "topic": "Deportes", "title": "Cafetaleros de Chiapas mantienen el invicto en casa", "author": "Chiapas Hoy//MdR", "text": "Loros se llevaba inmerecido premio de Chiapas, pero Cafetaleros rescat\u00f3 la igualada a un tanto en el Reyna\nCafetaleros de Chiapas se mantiene sin conocer derrota en casa y fue con un empate a uno ante Loros de Colima como el cuadro chiapaneco se mantiene con esta etiqueta en el V\u00edctor Manuel Reyna.\nUn juego que se inclin\u00f3 mejor para Cafetaleros en el segundo tiempo, result\u00f3 con un empate a uno en esta fecha seis del Ascenso BBVA MX; Loros de Colima, quien lleg\u00f3 a este circuito para esta temporada se met\u00eda a la casa de los Cafetaleros en busca de una victoria, misma que se palp\u00f3 pero no concret\u00f3.\nLoros se vio mejor en el primer tiempo cuando respondi\u00f3 series de llegadas al arco de Vel\u00e1zquez, quien atento a lo presentado por los colimenses, mantuvo el arco en cero; sin embargo, a pesar de la insistencia de los locales, Loros de Colima pudo haberse ido al vestido con un marcador a favor.En la segunda parte, cuando mejor futbol despleg\u00f3 Cafetaleros de Chiapas, la falta de gol hizo librar a los visitantes que por un momento mostraron nerviosismo, sin embargo, una oportunidad de contragolpe gener\u00f3 el tanto a los colimenses en este encuentro.\nCuando los chiapanecos atacaron el \u00e1rea de Loros, entre la combinaci\u00f3n de Franco Arizala y Chritian Berm\u00faez, el gol no llegaba y el crecimiento en domino de bal\u00f3n era mayor para los locales; Sim\u00f3n Almeyda hacia su aporte en el ataque por la banda izquierda y los centros al \u00e1rea rival que no encontraron pierna alguna para completar un gol.A los 74 minutos, \u201cHobbit\u201d Berm\u00fadez y Arizala hac\u00edan de la suya en el \u00e1rea contraria, pero la intervenci\u00f3n de Miguel Tejeda y el poste, ahogaban el grito de gol en la afici\u00f3n chiapaneca.En la b\u00fasqueda de concretar el gol, Loros aprovech\u00f3 la \u00fanica oportunidad para generar peligro con un solo hombre en la zona baja de Cafetaleros, por lo que Luis Garc\u00eda no dud\u00f3 en poner potencia a sus zancadas y cruzar el esf\u00e9rico a Carlos Vel\u00e1zquez, con lo que venci\u00f3 al guardameta local para el 1-0.Cafetaleros trat\u00f3 de responder, aunque como se esperaba, los visitantes se metieron a defender su zona y tratar de sacar los cuatro puntos. Para fortuna de Cafetaleros, Jairo V\u00e9lez ocup\u00f3 bien la pradera derecha para generar peligro constante y entrar al \u00e1rea y poner el zapatazo que Juan de Alba desvi\u00f3 para igualar los cartones al minuto 86.\nCon ello, Cafetaleros de Chiapas se fue al frente para invertir el n\u00famero y quedarse con el triunfo, pero Loros contaba con la buena suerte para guardar un punto en esta fecha del Ascenso MX.Con este tercer empate de la temporada, Cafetaleros lleg\u00f3 a seis puntos en el torneo, esperando conseguir la victoria en patio ajeno, cuando visite a Dorados en la fecha siete del Apertura 2019.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/deportes/cafetaleros-de-chiapas-mantienen-el-invicto-en-casa/"},
{"date": "2019/09/17", "topic": "Seguridad", "title": "Hist\u00f3rica participaci\u00f3n de la Fiscal\u00eda del Estado en desfile c\u00edvico militar en Chiapas: Llaven Abarca", "author": "Chiapas Hoy//MdR", "text": "La FGE particip\u00f3 con elementos de la Polic\u00eda Especializada, equipo canino de rastreo y detecci\u00f3n de drogas y enervantes, personal de Justicia Restaurativa y demostraci\u00f3n de veh\u00edculos t\u00e1cticos y de seguridad.\nTuxtla Guti\u00e9rrez, Chiapas.- El fiscal general Jorge Luis Llaven Abarca acompa\u00f1\u00f3 al gobernador Rutilio Escand\u00f3n Cadenas al izado de bandera y al desfile c\u00edvico militar, en\u00a0el marco de los festejos para conmemorar el 209 aniversario de la Independencia de M\u00e9xico, acto en el que por primera vez particip\u00f3 personal de la Fiscal\u00eda General del Estado.\nEn entrevista, Llaven Abarca destac\u00f3 que en los festejos c\u00edvicos militares se hizo patente la suma de voluntades de las autoridades militares, integrantes del gabinete, autoridades municipales y sociedad civil, por trabajar como un solo equipo en el fortalecimiento de nuestras ra\u00edces y principios de libertad y justicia.En ese sentido, el responsable de la procuraci\u00f3n de justicia en Chiapas destac\u00f3 que por primera vez la Fiscal\u00eda General del Estado form\u00f3 parte del desfile c\u00edvico militar: \u201cTodas las autoridades estamos unidas por un bien com\u00fan, que es la seguridad y la tranquilidad de las y los chiapanecos; y hoy m\u00e1s que nunca tenemos una procuraci\u00f3n de justicia siempre al lado de la gente\u201d, a\u00f1adi\u00f3.\nDetall\u00f3 que la Fiscal\u00eda del Estado refrenda su compromiso de garantizar el Estado de derecho y de trabajar de manera coordina con las diferentes instancias para enfrentar los retos de los tiempos actuales.\nEn el desfile, la FGE particip\u00f3 con elementos de la Polic\u00eda Especializada, equipo canino de rastreo y detecci\u00f3n de drogas y enervantes, personal de Justicia Restaurativa y demostraci\u00f3n de veh\u00edculos t\u00e1cticos y de seguridad.En el izado de bandera y el desfile c\u00edvico militar tambi\u00e9n estuvieron presentes: Rafael Adolfo Su\u00e1rez Gonz\u00e1lez, comandante de la XIV Zona Naval con sede en Puerto Chiapas, Juan Ernesto Antonio Bernal Reyes, comandante de la VII Regi\u00f3n Militar; Rosa Elizabeth Bonilla Hidalgo, presidenta del Honorable Congreso del Estado, Gabriela Zepeda Soto, secretaria de Seguridad y Protecci\u00f3n Ciudadana, entre otros.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/seguridad/historica-participacion-de-la-fiscalia-del-estado-en-desfile-civico-militar-en-chiapas-llaven-abarca/"},
{"date": "2019/09/17", "topic": "Deportes", "title": "Se concentr\u00f3 Selecci\u00f3n Chiapas de TKD rumbo a Juegos Nacionales de la CONADE y Eventos Federados.", "author": "Chiapas Hoy//MdR", "text": "Con intensos trabajos de entrenamientos f\u00edsicos y t\u00e9cnicos, se realiz\u00f3 la primera concentraci\u00f3n de la Selecci\u00f3n Chiapas de Tea Kwon Do de combate libre y formas , que se dio en el gimnasio de deportes de contacto del Instituto del Deporte, rumbo a los Juegos Nacionales de la CONADE y Eventos Federados del 2\u00b0 Semestre de la especialidad 2019-2020.\nTareas de revisi\u00f3n de los aspectos diferentes aspectos que se dio por espacio de cuatro horas, estuvieron a cargo del Profr. Allan L\u00f3pez La\u00ednez, destacado entrenador con curriculum de logros nacionales, que ahora integra al equipo Chiapas, auxiliado por los distintos profesores de las escuelas afiliadas, corrigieron las acciones de los 84 atletas de las categor\u00edas pre infantiles, infantiles, cadetes, juvenil y sub-20, provenientes de los municipios de Comit\u00e1n de Dom\u00ednguez, Ocosingo, Tapachula y Tuxtla Guti\u00e9rrez.\nEn entrevista con el titular de la Asociaci\u00f3n Chiapaneca de Tae Kwon Do (ACHTKD), Williams de Le\u00f3n Molina, dijo que fue una nutrida participaci\u00f3n al asistir un 95% de los preseleccionados estatales que hicieron el proceso en el estatal reciente al tiempo de se\u00f1alar que tambi\u00e9n se dieron cita los integrantes del cuerpo de staff, m\u00e9dicos y entrenadores que comparten los mismos objetivos de poner el nombre Chiapas en lo alto.\nIndic\u00f3 se preparan de cara a los selectivos nacionales que emplaza la Federaci\u00f3n Mexicana de Tae Kwon Do, teniendo como objetivo de aportar atletas a las selecciones nacionales y puedan consolidarse dentro de ellas. Se\u00f1al\u00f3 que los compromisos pr\u00f3ximos son el Nacional Abierto Mexiquense, El Selectivo Nacional de Adultos, La Copa Gobernador en Guerrero G3, Esperanzas Ol\u00edmpicas G3 en Chiapas, El Selectivo Nacional de Jalisco, Encuentro Nacional de Zacatecas de Poomsae, as\u00ed como la participaci\u00f3n de atletas del ParaTaekwondo \u201cCon un mismo objetivo de fogeuarse y poner el nombre de Chiapas en alto\u201d.\nAcent\u00fao que de manera paralela con la preparaci\u00f3n y participaci\u00f3n en los diferentes eventos nacionales federados, se hace el trabajo de cara a la participaci\u00f3n de los que integraran la Selecci\u00f3n Chiapas de la especialidad en el procesos de los Primeros Juegos Nacionales de la CONADE.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/deportes/se-concentro-seleccion-chiapas-de-tkd-rumbo-a-juegos-nacionales-de-la-conade-y-eventos-federados/"},
{"date": "2019/09/17", "topic": "Municipios", "title": "Encabeza Mariano Rosales Zuarth el grito de independencia desde Palacio Municipal en Villaflores", "author": "Chiapas Hoy//MdR", "text": "Ante miles de personas que llegaron de diversos puntos del pa\u00eds y el estado, el alcalde Mariano Rosales Zuarth acompa\u00f1ado por su familia y los miembros del cabildo encabez\u00f3 el tradicional grito de Independencia, recibi\u00f3 la bandera nacional de la escolta de la Guardia Nacional y se dirigi\u00f3 al balc\u00f3n de palacio para vitorear los nombres de los h\u00e9roes que nos dieron libertad.\nRosales\u00a0Zuarth visiblemente emocionado onde\u00f3 la ense\u00f1a nacional ante jubilosos espectadores que respondieron cada uno de los vivas con \u00edmpetu \u00a1\u00a1Viva M\u00e9xico!!, \u00a1\u00a1Viva la independencia nacional!!, \u00a1\u00a1Vivan los h\u00e9roes que nos dieron patria!!, \u00a1\u00a1Viva Hidalgo!!, \u00a1\u00a1Viva Allende!!, \u00a1\u00a1Viva Aldama!! \u00a1\u00a1Viva Villaflores!! \u00a1\u00a1Viva M\u00e9xico!!, \u00a1\u00a1Viva M\u00e9xico!!\nEn breve mensaje despu\u00e9s de la ceremonia el alcalde Rosales dijo que como mexicanos estamos cumpliendo con la gente y el cabildo que preside seguir\u00e1 trabajando en unidad por el progreso de Villaflores.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/estados/encabeza-mariano-rosales-zuarth-el-grito-de-independencia-desde-palacio-municipal-en-villaflores/"},
{"date": "2019/09/17", "topic": "TuxtlaHoy", "title": "SSyPC reporta saldo blanco en Fiestas Patrias 2019", "author": "Chiapas Hoy//MdR", "text": "Tuxtla Guti\u00e9rrez, Chiapas.- El Gobierno de Chiapas, a trav\u00e9s de la Secretar\u00eda de Seguridad y Protecci\u00f3n Ciudadana (SSyPC), que encabeza Gabriela Zepeda Soto, report\u00f3 saldo blanco durante las Fiestas Patrias 2019 en el territorio chiapaneco, como resultado de la participaci\u00f3n ciudadana y coordinaci\u00f3n interinstitucional de los tres \u00f3rdenes de gobierno.\n\u201cGracias a la coordinaci\u00f3n entre las instancias federales, estatales y municipales, y a que hubo una participaci\u00f3n ciudadana con civilidad y paz, obtuvimos saldo blanco durante las festividades patrias en el territorio chiapaneco, aunque se presentaron incidentes menores, pero nada que lamentar\u201d, se\u00f1al\u00f3 la titular de la SSyPC.Luego de la implementaci\u00f3n del operativo Fiestas Patrias 2019, a partir del viernes 13 y que concluy\u00f3 este lunes 16 de septiembre, donde se cont\u00f3 con una fuerza de tarea de m\u00e1s de 7 mil elementos de la Secretar\u00eda de Seguridad y Protecci\u00f3n Ciudadana (SSyPC), que trabajaron en coordinaci\u00f3n con las instancias de los tres \u00f3rdenes de gobierno, no se registraron acontecimientos que pusieran en riesgo la integridad f\u00edsica y patrimonial de la poblaci\u00f3n.El Plan Sistem\u00e1tico Operativo de Seguridad establecido con el objetivo de prevalecer la tranquilidad vio plasmado su esfuerzo al obtener un saldo blanco con incidentes menores, indic\u00f3 la funcionaria estatal.\n\u201cAfortunadamente no ha habido delitos de alto impacto, sin embargo, nos desplegamos en todos los municipios para evitar cualquier hecho lamentable, pero afortunadamente estas festividades muy emblem\u00e1ticas para los chiapanecos y mexicanos transcurrieron con en paz y calma\u201d, resalt\u00f3 Zepeda Soto.De igual forma, indic\u00f3 que estas acciones de seguridad y vigilancia que comprendieron la Gesta Heroica de los Ni\u00f1os H\u00e9roes de Chapultepec, el Aniversario de la Federaci\u00f3n de Chiapas a M\u00e9xico, Aniversario del Grito de Independencia de M\u00e9xico y el desfile c\u00edvico militar de la Conmemoraci\u00f3n del Inicio de la Independencia de M\u00e9xico, se aunaron al fin de semana largo, por lo que se resguardaron los 151 sitios tur\u00edstico con los que cuenta el territorio estatal.Con acciones como \u00e9stas, se refrenda el compromiso del Gobierno del Estado de seguir garantizando la seguridad de las chiapanecas y los chiapanecos.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/tuxtlahoy/ssypc-reporta-saldo-blanco-en-fiestas-patrias-2019/"},
{"date": "2019/09/17", "topic": "M\u00e9xicoHoy", "title": "Presidente L\u00f3pez Obrador encabeza el desfile militar de Independencia desde Palacio Nacional", "author": "Fuente: Notimex", "text": "La ceremonia del desfile militar por el 209 aniversario de la Independencia se inici\u00f3 con el izamiento y honores a la bandera nacional en el asta del Z\u00f3calo, as\u00ed c\u00f3mo el pase de revista a los contingentes por parte del presidente L\u00f3pez Obrador\nLa ceremonia del desfile militar por el 209 aniversario de la Independencia se inici\u00f3 con el izamiento y honores a la bandera nacional en el asta del Z\u00f3calo, as\u00ed c\u00f3mo el pase de revista a los contingentes por parte del presidente Andr\u00e9s Manuel L\u00f3pez Obrador.Acompa\u00f1ado de los secretarios de la Defensa Nacional y de Marina, Luis Cresencio Sandoval y Rafael Ojeda, el primer mandatario recorri\u00f3 la plancha del Z\u00f3calo a bordo de un veh\u00edculo militar.Previamentem, ocho aviones DC-6 y cinco F-5 surcaron el cielo capitalino en se\u00f1al del arranque de esta ceremonia por la gesta independiente, la primera que encabeza el presidente Lopez Obrador.De inmediato inici\u00f3 esta parada militar, encabezada por la Guardia Nacional y en el que participar\u00e1n 12 mil 492 elementos.Participan invitados internacionales de Guardias Nacionales como la Polic\u00eda Nacional de Argentina, los carabineros de Chile, la Guardia Civil Espa\u00f1ola, la Gendarmer\u00eda de Polonia y la Guardia Nacional Republicana de Portugal.\nDesfile diferente\nEl desfile en 2019 es diferente a otros a\u00f1os, pues adem\u00e1s de los elementos militares y Guardia Nacional, por primera vez se sumar\u00e1n personas de la tercera edad, j\u00f3venes y ni\u00f1os beneficiarios de los programas sociales, y las pipas que transportan el combustible para evitar el huachicol.Se muestran 55 banderas nacionales de guerra, seis banderas extranjeras, 83 soldados del servicio militar nacional y 85 alumnos de bachillerato militarizado.Tambi\u00e9n 68 charros y 10 paracaidistas de la Fuerza A\u00e9rea, entre ellos una mujer, y cinco de las fuerzas especiales de la Marina.\nTambi\u00e9n desfilar\u00e1n frente a Palacio Nacional 15 ni\u00f1os del programa Soldados Marinos Honorario, 94 trabajadores del Sistema Nacional de Protecci\u00f3n Civil, 12 de la Comisi\u00f3n Nacional del Agua.Asimismo, 20 de Petr\u00f3leos Mexicanos, 24 beneficiarios del Programa para el Bienestar de las Personas Adultas Mayores, nueve J\u00f3venes del programa construyendo el futuro, 40 ni\u00f1as y ni\u00f1os.\nRodar\u00e1n por las calles 416 veh\u00edculos, del Z\u00f3calo hasta el Auditorio Nacional; 218 caballos, y cruzar\u00e1n el cielo de la Ciudad de M\u00e9xico 74 aeronaves.\nDe acuerdo con informaci\u00f3n de la Secretaria de Seguridad Ciudadana, desde la 5:00 de la ma\u00f1ana la gente empez\u00f3 a llegar al primer cuadro de la capital para tener un lugar lo m\u00e1s cercano posible para ver este desfile.Alrededor de las 8:30 de la ma\u00f1ana, en las calles m\u00e1s cercanas al Z\u00f3calo la gente incluso ocup\u00f3 banquitos para no cansarse de pie, en lo que empezaba el desfile.De las estaciones del Metro Pino Su\u00e1rez y Bellas Artes miles de personas salieron para caminar hacia el Z\u00f3calo. Familias enteras, ni\u00f1os y ni\u00f1as, vestidas con trajes t\u00edpicos para continuar con los festejos patrios.\nFuente: Notimex", "url": "http://www.chiapashoy.com.mx/notashoy/mexicohoy/presidente-lopez-obrador-encabeza-el-desfile-militar-de-independencia-desde-palacio-nacional/"},
{"date": "2019/09/17", "topic": "Municipios", "title": "M\u00e1s de 3 mil alumnos participan en Desfile Civico Escolar: Humberto Molina", "author": "Chiapas Hoy//MdR", "text": "EL Honorable Ayuntamiento Constitucional de Chiapa de Corzo que encabeza el Lic. Jorge Humberto Molina G\u00f3mez, a trav\u00e9s de la Direcci\u00f3n de Fomento Educativo, con motivo de la celebraci\u00f3n de un Aniversario m\u00e1s de nuestra Independencia Nacional, realizaron un Desfile C\u00edvico Escolar Conmemorativo.\nEl Presidente se hizo acompa\u00f1ar de su distinguida esposa Lic. Sujey Orantes Molina, Presidenta del DIF Municipal y de su Honorable Cabildo.Durante este desfile participaron alrededor de once Escuelas enunciadas a continuaci\u00f3n; Escuela Primaria Salvador Urbina, Primaria Dr. Belisario Dom\u00ednguez, Primaria Francisco Gonz\u00e1lez Bocanegra, Primaria Chiapa unida, Primaria \u00c1ngel Albino Corzo, Escuela Secundaria 1\u00b0 de Marzo turno matutino, Escuela Secundaria Jos\u00e9 Emilio Grajales, Escuela secundaria 1\u00b0 de Marzo turno vespertino, COBACH, CONALEP, Escuela Preparatoria Florinda lazos Le\u00f3n, que en conjunto forman un total de 3 mil 255 alumnos.Cabe destacar que a la par de este Desfile C\u00edvico Escolar se llev\u00f3 a cabo un desfile a\u00e9reo que engalan\u00f3 la ma\u00f1ana, para cerrar con broche de oro este puente de celebraciones patrias que nos llenan de orgullo y tradici\u00f3n.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/estados/mas-de-3-mil-alumnos-participan-en-desfile-civico-escolar-humberto-molina/"},
{"date": "2019/09/17", "topic": "ChiapasHoy", "title": "Clausura fiscal conferencia magistral \u201cLa Acci\u00f3n Penal Privada\u201d", "author": "Chiapas Hoy//MdR", "text": "Tuxtla Guti\u00e9rrez, Chiapas.- En el marco de la clausura de la conferencia magistral \u201cLa Acci\u00f3n Penal Privada\u201d impartida por V\u00edctor Ol\u00e9a Pel\u00e1ez, segundo vicepresidente del Consejo Directivo de la Barra Mexicana, Colegio de Abogados A.C.; el fiscal general destac\u00f3 que es fundamental brindar herramientas a las y los servidores p\u00fablicos para una procuraci\u00f3n de justicia eficiente y eficaz.\nAcompa\u00f1ado por Jorge Segismundo Rotter D\u00edaz, fiscal de Procedimientos Penales; Francisco Castillo Acevedo, presidente de la Barra Mexicana, Colegio de Abogados A.C., Cap\u00edtulo Chiapas; Ignacio Alejandro Vila Ch\u00e1vez, delegado de la Fiscal\u00eda General de la Rep\u00fablica; y el ponente V\u00edctor Olea Pel\u00e1ez; Llaven Abarca refrend\u00f3 su compromiso para abrir m\u00e1s espacios de debate, conferencias y conversatorios para un mejor desempe\u00f1o en las funciones p\u00fablicas.\n\u201cTenemos que enfocar esfuerzos para la preparaci\u00f3n del personal que labora en la Fiscal\u00eda del Estado, ya que para brindar un servicio de calidad a la ciudadan\u00eda se requiere de profesionistas que cuenten con las herramientas indispensables para integrar una investigaci\u00f3n, para litigar ante los \u00f3rganos jurisdiccionales y desde luego para buscar las salidas alternativas a los conflictos en los supuestos y con las condiciones que la propia norma establece\u201d, declar\u00f3 el responsable de procuraci\u00f3n de justicia en Chiapas.\nAsimismo, en el marco de la clausura de este evento organizado por el Instituto de Investigaci\u00f3n y Profesionalizacion de la FGE, Llaven Abarca agradeci\u00f3 la presencia de V\u00edctor Olea Pel\u00e1ez por compartir su experiencia y su conocimiento sobre la Acci\u00f3n Penal Privada en el nuevo Sistema de Justicia Penal y a la Barra Mexicana Cap\u00edtulo Chiapas por trabajar de la mano con la Fiscal\u00eda para fomentar la actualizaci\u00f3n jur\u00eddica, capacitaci\u00f3n y el estudio del derecho.\n\u201cEl nuevo modelo acusatorio lleva a las manos del pueblo la justicia en los delitos, donde el mayor agravio lo reciente la v\u00edctima y al mismo tiempo descongestiona la carga de trabajo para enfocarse en los asuntos de mayor impacto social. Festejo que estemos reunidos tanto quienes se dedican al litigio y servidores p\u00fablicos con vocaci\u00f3n, ya que somos corresponsables de la justicia, de la equidad y de que la sociedad est\u00e9 satisfecha o insatisfecha de los procesos judiciales en materia penal\u201d, expuso Llaven Abarca.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/chiapashoy/clausura-fiscal-conferencia-magistral-la-accion-penal-privada/"},
{"date": "2019/09/17", "topic": "Municipios", "title": "Icheja e INEA avanzan en el combate al analfabetismo en Las Margaritas y La Trinitaria", "author": "Chiapas Hoy//MdR", "text": "En Las Margaritas firman convenio \u201cEl Buen Juez, por su casa empieza\u201d\nLas Trinitaria, Chis.- Con la finalidad de seguir combatiendo el analfabetismo en Chiapas, en un trabajo de unidad entre el Instituto Chiapaneco de Educaci\u00f3n para J\u00f3venes y Adultos (Icheja) y el Instituto Nacional para la Educaci\u00f3n de los Adultos (INEA), se hizo entrega de certificados de primaria y secundaria a personas de Las Margaritas y La Trinitaria que culminaron satisfactoriamente estos niveles educativos.\nAl encabezar este acto, desde la cabecera municipal de La Trinitaria, el director general del Icheja, Gustavo G\u00f3mez Ordo\u00f1ez, reconoci\u00f3 el esfuerzo y entusiasmo de los educandos por seguir adelante y ser constantes, ya que, dijo, para los gobiernos de Andr\u00e9s Manuel L\u00f3pez Obrador y de Rutilio Escand\u00f3n Cadenas, la educaci\u00f3n es unos de las prioridades, principalmente en aquellas personas que a\u00fan no saben leer y escribir.\nG\u00f3mez Ordo\u00f1ez reconoci\u00f3 el apoyo que han recibido por parte del alcalde de La Trinitaria, Ervin Leonel P\u00e9rez Alfaro, quien est\u00e1 comprometido en trabajar junto al Icheja, para que m\u00e1s j\u00f3venes y adultos puedan aprender a leer y escribir o en sus caso, concluir con la educaci\u00f3n primaria o secundaria.En este marco, se hizo entrega de un reconocimiento a la asesora, Mar\u00eda Guadalupe Conde Alfonso, por sus 38 a\u00f1os de servicio en el INEA.\nPosteriormente, G\u00f3mez Ordo\u00f1ez firm\u00f3 el convenio de colaboraci\u00f3n \u201cEl Buen Juez por su Casa Empieza\u201d con el Ayuntamiento de Las Margaritas, el cual tiene como objetivo primordial la promoci\u00f3n y el \u00e1nimo para que los servidores p\u00fablicos de las dependencias municipales puedan concluir la educaci\u00f3n b\u00e1sica y a continuar con sus estudios a trav\u00e9s del Modelo Educativo para la Vida y el Trabajo (MEVyT).\nEstuvieron presentes, por el Icheja: el secretario T\u00e9cnico, Oscar Miguel S\u00e1nchez Alpuche; el coordinador Regional de la Zona Costa; \u00d3scar Antonio Cruz Hern\u00e1ndez; as\u00ed como funcionarios municipales y trabajadores del Icheja.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/estados/icheja-e-inea-avanzan-en-el-combate-al-analfabetismo-en-las-margaritas-y-la-trinitaria/"},
{"date": "2019/09/17", "topic": "Municipios", "title": "Viridiana Hern\u00e1ndez realiza acto conmemorativo del grito de Independencia.", "author": "Chiapas Hoy//MdR", "text": "En un acto protocolario, la presidenta Municipal de Simojovel Viridiana Hern\u00e1ndez S\u00e1nchez, encabez\u00f3 el grito de Independencia en el municipio de Simojovel.La presidente Viridiana Hern\u00e1ndez da su primer Grito de IndependenciaEsta noche, cientos de mexicanos se dieron cita en el parque Central para la primera ceremonia del Grito de Independencia de M\u00e9xico. Poniendo en alto los que nos dieron patria y libertad a los h\u00e9roes, junto a cientos de personas que gritaron las \u201cvivas\u201d, en el parque central.Acompa\u00f1ado de regidores y directores de las administraci\u00f3n municipal, as\u00ed como la escolta de la Guardia Nacional la primera Autoridad de Simojovel, salud\u00f3 a los ciudadanos que se dieron cita. Donde disfrutaron de ricos antojitos Mexicanos y disfrutaro del mariachi Tony Mi Pa\u00eds y el Grupo Aut\u00e9ntico Show.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/estados/viridiana-hernandez-realiza-acto-conmemorativo-del-grito-de-independencia/"},
{"date": "2019/09/17", "topic": "Municipios", "title": "Ocozocoautla se visti\u00f3 de gala con el desfile civico conmemorativo al 209 aniversario de la independencia de M\u00e9xico.", "author": "Chiapas Hoy//MdR", "text": "Ocozocoautla, Chiapas. Septiembre del 2019.- Con la participaci\u00f3n de cinco instituciones educativas se desarroll\u00f3 sin incidentes el desfile c\u00edvico conmemorativo al 209 aniversario de la Independencia de M\u00e9xico.El Presidente Municipal, Alfonso Estrada P\u00e9rez junto a la Presidenta del sistema DIF, Estrella Hern\u00e1ndez D\u00edaz, regidores y funcionarios presenciaron el\u00a0evento que forma parte del mes patrio.Los contingentes pasaron frente a la Presidencia Municipal donde recibieron los aplausos de las autoridades y del p\u00fablico asistente que desde muy temprano esper\u00f3 con emoci\u00f3n el desfile.Particip\u00f3 el Colegio Jean Piaget, Preparatoria N\u00famero 1, Cobach 49, Icheja y Telesecundaria 098 con bonitos trajes t\u00edpicos regionales mexicanos que hicieron m\u00e1s emotivo el evento.El Alcalde Alfonso Estrada reconoci\u00f3 a los planteles educativos por su participaci\u00f3n y agradeci\u00f3 la presencia de los ciudadanos que por tradici\u00f3n siempre asisten a presencia este desfile c\u00edvico.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/estados/ocozocoautla-se-vistio-de-gala-con-el-desfile-civico-conmemorativo-al-209-aniversario-de-la-independencia-de-mexico/"},
{"date": "2019/09/17", "topic": "Municipios", "title": "Toledo Blas encabeza ceremonia del grito de independencia en Arriaga", "author": "Chiapas Hoy//MdR", "text": "Arriaga, Chiapas.- El presidente municipal Jos\u00e9 Alfredo Toledo Blas, encabez\u00f3 la Ceremonia del Grito de Independencia desde el Palacio Municipal, donde estuvo acompa\u00f1ado de las regidoras Olga Mayreli Aguilar Rasgado, Mar\u00eda Concepci\u00f3n Palacios Moguel, Mar\u00eda Alejandra Mart\u00ednez Bezares y Ana Luc\u00eda Ru\u00edz D\u00edaz y de directores de \u00e1reas.En el marco del 209 aniversario del inicio de la Independencia de M\u00e9xico, el alcalde Toledo Blas desde el balc\u00f3n del Palacio Municipal realiz\u00f3 el acto protocolario oficial iniciando con los honores al L\u00e1baro Patrio para posteriormente realizar el tradicional Grito de Independencia recordando a los h\u00e9roes que lucharon por la libertad de la naci\u00f3n.\nExpres\u00f3 \u201choy es una de las fechas m\u00e1s importantes para los mexicanos ya que se conmemora el aniversario del inicio de la independencia de M\u00e9xico con el tradicional grito que se da en las principales ciudades del pa\u00eds\u201d.Abund\u00f3 La ceremonia del Grito recuerda el llamado que hizo el cura Miguel Hidalgo y Costilla la madrugada del 16 de septiembre de 1810, cuando al hacer sonar la campana de la iglesia de Dolores Hidalgo, convoc\u00f3 al pueblo a levantarse en armas en contra del dominio espa\u00f1ol.\nEl alcalde y regidoras agradecieron al pueblo arriaguense por formar parte de estas acciones que fomentan los valores c\u00edvicos, as\u00ed como el respaldo a este nuevo gobierno para el periodo 2019-2021 de gesti\u00f3n y administraci\u00f3n.\nPosterior al acto c\u00edvico las autoridades ofrecieron a los asistentes una verbena popular que fue amenizada por la banda Diamante quienes interpretaron sus grandes \u00e9xitos y el comediante Mr. Yo-Yer qui\u00e9n hizo re\u00edr a todas las familias.Con algarab\u00eda, civilidad, fervor patri\u00f3tico y unidad el gobierno y pueblo hicieron una gran velada, lo que propici\u00f3 un ambiente de paz, tranquilidad y armon\u00eda sin incidentes que lamentar.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/estados/toledo-blas-encabeza-ceremonia-del-grito-de-independencia-en-arriaga/"},
{"date": "2019/09/17", "topic": "Municipios", "title": "Roberto Pinto, preside Desfile C\u00edvico Militar en Conmemoraci\u00f3n del 209 Aniversario del inicio de la Independencia.", "author": "Chiapas Hoy//MdR", "text": "Los festejos patrios culminan en Altamirano con un saldo blanco.\nEl Presidente Municipal de Altamirano, Lic. Roberto Pinto Kanter, acompa\u00f1ado del Teniente Coronel de Infanter\u00eda, Luis Antonio Salinas Morales, Comandante de la 11\u00ba/C.I.N.E, e integrantes del honorable cabildo, encabez\u00f3 este lunes 16 de septiembre del 2019, el Desfile C\u00edvico Militar en Conmemoraci\u00f3n\u00a0del 209 Aniversario del inicio de la independencia de M\u00e9xico.\nDurante cerca 60 minutos el Mandatario Municipal presencio el paso de los diversos contingentes integrados en su inicio por la escolta de la Polic\u00eda Municipal, del Centro de Atenci\u00f3n M\u00faltiple (CAM), Centro de Atenci\u00f3n Infantil Comunitario (CAIC), Jardines de ni\u00f1as y ni\u00f1os, Rosario Castellanos y Fernando Montes de Oca, as\u00ed como el Centro de Estudios Cient\u00edficos y Tecnol\u00f3gicos plantel 43 la laguna, CONALEP 331, COBACH Plantel 45, personal del Ayuntamiento, DIF Altamirano, y la participaci\u00f3n de los elementos de la Secretaria de la Defensa Nacional a trav\u00e9s de la comandancia de la 11/a.C.I.N.E, culminando con la Asociaci\u00f3n de Charros de Altamirano, quienes recorrieron las principales calles de esta cabecera municipal.\nAl termino del desfile el mun\u00edcipe expres\u00f3 su emoci\u00f3n y alegr\u00eda por la excelente participaci\u00f3n de la ciudadan\u00eda altamiranense en estas festividades patrias, agradeciendo la participaci\u00f3n de los contingentes quienes engalanaron el cierre de estos festejos patrios 2019, culminando con un saldo blanco.Con ello se demuestra el resultado del trabajo que se viene realizando con los tres \u00f3rdenes de gobierno por la paz y gobernabilidad.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/estados/roberto-pinto-preside-desfile-civico-militar-en-conmemoracion-del-209-aniversario-del-inicio-de-la-independencia/"},
{"date": "2019/09/17", "topic": "Municipios", "title": "Grupo de vecinos casi linchan a presunto ladr\u00f3n", "author": "Fuente: V\u00f3rticeMX", "text": "San Crist\u00f3bal de Las Casas. \u2013 Un joven estuvo a punto de ser linchado luego de que fuera sorprendido intentando llevarse una bicicleta en el barrio San Diego, del municipio de San Crist\u00f3bal de Las Casas.De acuerdo con datos obtenidos, el propietario al parecer se encontraba sacando un duplicado de unas llaves sobre la calle Insurgentes y esquina con la avenida Valent\u00edn G\u00f3mez Far\u00edas.Sin embargo, en ese momento se percat\u00f3 que, una persona se estaba llevando su bicicleta y a gritos comenz\u00f3 a pedir ayuda.Fue que, un grupo de personas organizadas comenzaron a zonas sus silbatos y en cuesti\u00f3n de segundos se aglomeraron y comenzaron a perseguir al presunto ladr\u00f3n el cual amarraron a un poste.Finalmente, solicitaron el apoyo de los cuerpos de seguridad quienes subieron al acusado a una patrulla.\nFuente: V\u00f3rticeMX", "url": "http://www.chiapashoy.com.mx/notashoy/estados/grupo-de-vecinos-casi-linchan-a-presunto-ladron/"},
{"date": "2019/09/17", "topic": "Internacional", "title": "No necesitamos el petr\u00f3leo y el gas de Medio Oriente: Trump", "author": "Chiapas Hoy//MdR", "text": "Donald Trump asegur\u00f3 este lunes que Estados Unidos no necesita el petr\u00f3leo de Medio Oriente, en momentos en que el precio se dispar\u00f3 tras el ataque de drones a plantas de Arabia Saudita.\n\u201cSomos un exportador neto de energ\u00eda y ahora el productor de energ\u00eda n\u00famero uno en el mundo\u201d, escribi\u00f3 en Twitter.\u201cNo necesitamos el petr\u00f3leo y el gas de Medio Oriente y en realidad tenemos muy pocos cargueros all\u00ed, pero ayudaremos a nuestros aliados\u201d, a\u00f1adi\u00f3 el mandatario republicano.Estados Unidos es el primer productor de petr\u00f3leo del mundo, con 18 millones de barriles por d\u00eda en 2018, seg\u00fan la Agencia de Informaci\u00f3n Energ\u00e9tica (EIA).\nArabia Saudita es el primer exportador mundial de crudo y el segundo productor.El precio del petr\u00f3leo se dispar\u00f3 este lunes en Londres tras los ataques contra infraestructuras petroleras en Arabia Saudita el s\u00e1bado, que redujeron a la mitad la producci\u00f3n del pa\u00eds y acentuaron los temores de escalada militar entre Estados Unidos e Ir\u00e1n.\nLos bombardeos fueron reivindicados por rebeldes hut\u00edes de Yemen, que se enfrentan desde hace cinco a\u00f1os a una coalici\u00f3n militar liderada por Arabia Saudita y cuentan con el respaldo de Ir\u00e1n.Ante la reducci\u00f3n de la producci\u00f3n saudita, Trump autoriz\u00f3 el domingo el uso de petr\u00f3leo de las reservas estrat\u00e9gicas del pa\u00eds y dijo que est\u00e1 listo para responder al ataque.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/internacional/no-necesitamos-el-petroleo-y-el-gas-de-medio-oriente-trump/"},
{"date": "2019/09/17", "topic": "M\u00e9xicoHoy", "title": "Ricardo Monreal presentar\u00e1 iniciativa para incentivar donaci\u00f3n de \u00f3rganos", "author": "Chiapas Hoy//MdR", "text": "Ricardo Monreal, senador de Morena, destac\u00f3 que en nuestro pa\u00eds hay miles de personas que requieren un trasplante\nEl coordinador de Morena en el Senado, Ricardo Monreal, presentar\u00e1 una iniciativa para incentivar la donaci\u00f3n de \u00f3rganos en nuestro pa\u00eds y perfeccionar el modelo regulatorio en la materia.La propuesta, que plantea reformar la Ley General de Salud, busca promover la cultura de la donaci\u00f3n de \u00f3rganos, por lo que prev\u00e9 incorporar mecanismos que permitan aumentar el \u00edndice de personas dispuestas a salvar o ayudar a otra.\nAdem\u00e1s, establece el principio de reciprocidad en la asignaci\u00f3n de \u00f3rganos para trasplante, con lo cual se dar\u00e1 prioridad -en las listas de espera- a las personas que emitieron su consentimiento para donar sus \u00f3rganos despu\u00e9s de su muerte. Adem\u00e1s, la iniciativa prev\u00e9 facultar a la Secretar\u00eda de Salud para que establezca los mecanismos de priorizaci\u00f3n y determine las eventuales excepciones, considerando el estado de gravedad de la persona receptora.Ricardo Monreal destac\u00f3 que en nuestro pa\u00eds hay miles de personas que requieren un trasplante. Indic\u00f3 que la falta de \u00f3rganos y tejidos disponibles obliga a registrarse en una lista de espera, alargando el sufrimiento del paciente y su familia.El senador por Morena record\u00f3 que, de acuerdo con el Centro Nacional de Trasplantes, durante el primer semestre de 2019 hubo 22 mil 290 personas en espera de un \u00f3rgano o un tejido; sin embargo, s\u00f3lo mil 226 recibieron \u00f3rganos provenientes de personas fallecidas. \u200b\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/mexicohoy/ricardo-monreal-presentara-iniciativa-para-incentivar-donacion-de-organos/"},
{"date": "2019/09/17", "topic": "Internacional", "title": "GM y trabajadores reinician negociaciones luego de huelga", "author": "Chiapas Hoy//MdR", "text": "Desde la medianoche del domingo, empleados se han situado en las entradas de las plantas de producci\u00f3n de GM en Michigan y otros estados del pa\u00eds en defensa de la huelga.\nGeneral Motors (GM) y el sindicato United Auto Workers (UAW) reiniciaron este lunes las negociaciones para la firma de un contrato colectivo despu\u00e9s de que 46.000 empleados del fabricante en Estados Unidos iniciaran una huelga a medianoche del domingo.\nLa huelga, la primera que sufre GM desde 2007, se inici\u00f3 despu\u00e9s de que las negociaciones entre la empresa y el sindicato quedaran estancadas tras dos meses de conversaciones sobre reivindicaciones salariales y de prestaciones sociales de los trabajadores.Uno de los principales problemas es la oferta inicial de GM de pagar un 15 % de los gastos sanitarios de sus trabajadores, lo que supone la mitad de la media nacional.\nEl vicepresidente de UAW Terry Dittes, se\u00f1al\u00f3 en un comunicado que los trabajadores de GM defendieron la empresa \u201ccuando m\u00e1s nos necesitaban\u201d y que ahora los empleados est\u00e1n unidos para defender \u201ca nuestros afiliados, sus familias y las comunidades en las que trabajamos y vivimos\u201d.Por su parte, GM se\u00f1al\u00f3 en un comunicado que ha ofrecido a UAW 7.000 millones de d\u00f3lares en inversiones durante la duraci\u00f3n del contrato colectivo lo que crear\u00e1 m\u00e1s de 5.400 empleos y mejorar\u00e1 salarios y prestaciones sanitarias.\u201cHemos negociado en buena fe y con un sentido de urgencia. Nuestro objetivo sigue siendo construir un fuerte futuro para nuestros empleados y la empresa\u201d, dijo GM.A pesar de la oferta de GM, los trabajadores de UAW consiguieron hoy el respaldo de destacados pol\u00edticos dem\u00f3cratas.Juli\u00e1n Castro, uno de los candidatos a la nominaci\u00f3n presidencial dem\u00f3crata destac\u00f3 que Twitter que la consejera delegada del gigante automovil\u00edstico, Mary Barra, gan\u00f3 22 millones de d\u00f3lares en 2018, \u201c281 veces el salario medio de un trabajador de GM\u201d y que la empresa puede permitirse mejorar las condiciones econ\u00f3micas de sus empleados.Otro candidato dem\u00f3crata, Bernie Sanders, expres\u00f3 su apoyo en los trabajadores \u201cque est\u00e1n enfrent\u00e1ndose a la avaricia de GM\u201d.\u201cNuestro mensaje a GM es simplemente este: punto final a la avaricia, negocie con UAW y trabaje por un acuerdo que trata a los trabajadores con el respeto y la dignidad que se merecen\u201d.Por su parte, la gobernadora de Michigan, Gretchen Whitmer, defendi\u00f3 a UAW y su lucha por \u201cbuenos empleos y salarios justos\u201d.\u201cEspero que UAW y GM puedan negociar y ratificar pronto un contrato para que los trabajadores del sector del autom\u00f3vil de Michigan puedan regresar a sus puestos de trabajo lo antes posible porque es muy importante para nuestra econom\u00eda\u201d, a\u00f1adi\u00f3 Whitmer.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/internacional/gm-y-trabajadores-reinician-negociaciones-luego-de-huelga/"},
{"date": "2019/09/17", "topic": "M\u00e9xicoHoy", "title": "Estado de salud de paracaidista lesionado se reporta estable", "author": "Chiapas Hoy//MdR", "text": "El secretario de Marina, almirante Jos\u00e9 Rafael Ojeda Dur\u00e1n, y esposa, visitaron al militar y a su familia, brind\u00e1ndoles el apoyo para su pronta recuperaci\u00f3n\nLa Secretar\u00eda de Marina (Semar) inform\u00f3 que el estado de salud del segundo maestre, Infante de Marina Fuerzas Especiales, Valente Mateo Hern\u00e1ndez, se reporta como estable.Detall\u00f3 que el paracaidista naval realiz\u00f3 un ejercicio de infiltraci\u00f3n a gran altura, en el cual al momento de llevar a cabo su aterrizaje frente a Palacio Nacional, basado en su adiestramiento especializado y derivado de los c\u00e1lculos de espacio y maniobra, tom\u00f3 la decisi\u00f3n de usar una zona de aterrizaje alterna, esto con el fin de evitar poner en riesgo la vida de otros paracaidistas o inclusive de los espectadores, acci\u00f3n que le provoc\u00f3 lesiones f\u00edsicas.\nEl infante de Marina de manera inmediata fue trasladado al Centro M\u00e9dico Naval (CEMENAV), donde fue diagnosticado con traumatismo craneoencef\u00e1lico leve, herida de nariz y probable fractura de tobillo.\nAl t\u00e9rmino del desfile militar, el secretario de Marina, almirante Jos\u00e9 Rafael Ojeda Dur\u00e1n, y esposa, visitaron al militar y a su familia, brind\u00e1ndoles el apoyo para su pronta recuperaci\u00f3n y buena estad\u00eda durante su proceso de rehabilitaci\u00f3n.La Semar destac\u00f3 que la Unidad de Operaciones Especiales tiene como prop\u00f3sito proyectar tropas, comandos y fuerzas especiales de Infanter\u00eda de Marina de manera inmediata y decidida como parte de una fuerza de reacci\u00f3n o como un medio de infiltraci\u00f3n sorpresivo, r\u00e1pido y efectivo salvando obst\u00e1culos que por otros medios serian inapropiados.Estas tropas, siempre se han distinguido por la calidad de sus elementos, as\u00ed como la lealtad y firmeza de sus combatientes; actualmente son parte de las fuerzas de r\u00e1pido despliegue y son consideradas como una reserva estrat\u00e9gica para los mandos militares.Es importante mencionar que, las operaciones a\u00e9reas que el personal de paracaidistas desarrolla en cada misi\u00f3n es de una alta dificultad, por lo que siempre representa un margen de riesgo para quienes lo realizan.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/mexicohoy/estado-de-salud-de-paracaidista-lesionado-se-reporta-estable/"},
{"date": "2019/09/17", "topic": "M\u00e9xicoHoy", "title": "Muere a los 85 a\u00f1os Gabriel Fern\u00e1ndez, esposo de \u201cLa Chilindrina", "author": "Fuente: Agencias", "text": "Este pasado domingo muri\u00f3 a los 85 a\u00f1os a\u00f1os Gabriel Fern\u00e1ndez, quien en vida fuera esposo de la actriz Mar\u00eda Antonieta de las Nieves, mejor conocida como \u201cLa Chilindrina\u201c.La noticia fue confirmada en Instagram por el actor Carlos Villagr\u00e1n, quien interpret\u00f3 a \u201cKiko\u201d en la serie televisiva \u201cEl Chavo del 8\u201c.\u201cCon pesar comparto la tristeza de mi gran amiga y compa\u00f1era de grandes experiencias, Mar\u00eda Antonieta de\u00a0las Nieves, por la partida de tambi\u00e9n mi gran amigo Gabo\u201d, escribi\u00f3 \u201cKiko\u201d.De acuerdo con medios especializados, Gabriel Fern\u00e1ndez estaba internado en un hospital de M\u00e9xico luego de que enfermara de neumon\u00eda; sin embargo, hasta el momento no se ha informado la causa de muerte.\nFuente: Agencias", "url": "http://www.chiapashoy.com.mx/notashoy/mexicohoy/muere-a-los-85-anos-gabriel-fernandez-esposo-de-la-chilindrina/"},
{"date": "2019/09/17", "topic": "M\u00e9xicoHoy", "title": "Senado tendr\u00e1 una representaci\u00f3n de los atletas que participaron en Lima", "author": "Chiapas Hoy//MdR", "text": "El Senado de la Rep\u00fablica acord\u00f3 celebrar una sesi\u00f3n solemne, el pr\u00f3ximo 10 de octubre, para recibir a una representaci\u00f3n de los atletas que participaron en la XVIII edici\u00f3n de los Juegos Panamericanos, as\u00ed como en los VI Juegos Parapanamericanos, celebrados en Lima, Per\u00fa.En un punto de acuerdo, los senadores resaltaron que la delegaci\u00f3n de atletas mexicanos tuvo una hist\u00f3rica participaci\u00f3n, pues logr\u00f3 obtener casi 300 medallas en los dos eventos deportivos.\nRecordaron que la LXIV Legislatura de la C\u00e1mara Alta ha enfatizado su apoyo a la juventud y el amplio reconocimiento a los deportistas mexicanos, buscando dar la merecida importancia al desempe\u00f1o que tuvieron los deportistas de nuestro pa\u00eds.Por ello, acordaron celebrar una sesi\u00f3n solemne a fin de recibir una representaci\u00f3n de atletas mexicanos que participaron en los pasados juegos de Lima 2019.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/mexicohoy/senado-tendra-una-representacion-de-los-atletas-que-participaron-en-lima/"},
{"date": "2019/09/17", "topic": "M\u00e9xicoHoy", "title": "CNDH pide que pol\u00edtica migratoria se centre en las personas y no en acuerdos comerciales", "author": "Chiapas Hoy//MdR", "text": "La Comisi\u00f3n Nacional de los Derechos Humanos (CNDH) afirm\u00f3 que los acuerdos comerciales no deben estar sobre la dignidad de las personas, por lo cual demand\u00f3 al Gobierno federal que en su pol\u00edtica migratoria ponga en el centro a las personas sin restar importancia a dichos acuerdos.\nAsimismo, destac\u00f3 que invertir en Centroam\u00e9rica y el sureste mexicano es un proyecto de mediano plazo, y mientras ello ocurre hay que atender los problemas, porque se trata de vidas, integridades y la esperanza de una ni\u00f1ez ajena a lo que los pa\u00edses no han hecho para lograr una distribuci\u00f3n m\u00e1s equitativa del potencial que como humanidad tenemos.\nEn el marco de la presentaci\u00f3n del estudio \u201cPol\u00edticas de Inmigraci\u00f3n de los Estados Unidos, Derechos Humanos; el ombudsperson nacional, Luis Ra\u00fal Gonz\u00e1lez P\u00e9rez, lament\u00f3 que la gran aspiraci\u00f3n de regular la migraci\u00f3n en Estados Unidos se haya olvidado al privilegiar la politizaci\u00f3n ideol\u00f3gica del fen\u00f3meno en diferentes administraciones, lo cual se acentu\u00f3 en el gobierno del presidente Donald Trump, como la violaci\u00f3n de la ley y los derechos humanos de la ni\u00f1ez migrante.Asimismo, conden\u00f3 que la autoridad norteamericana niegue servicios b\u00e1sicos como higiene y salud; tenga hacinados a ni\u00f1os migrantes en las oficinas y lament\u00f3 que no se haya logrado la reunificaci\u00f3n total de familias, a pesar de las \u00f3rdenes de las Cortes americanas y de la excitativa de la Comisi\u00f3n Interamericana de Derechos Humanos para la protecci\u00f3n de familias y las medidas cautelares solicitadas por la CNDH.Gonz\u00e1lez P\u00e9rez dijo que los problemas deben reconocerse para resolverlos, y subray\u00f3 la importancia de esa investigaci\u00f3n que aborda los efectos de la pol\u00edtica migratoria de los Estados Unidos sobre los derechos humanos de las personas migrantes con \u00e9nfasis en la ni\u00f1ez.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/mexicohoy/cndh-pide-que-politica-migratoria-se-centre-en-las-personas-y-no-en-acuerdos-comerciales/"},
{"date": "2019/09/17", "topic": "M\u00e9xicoHoy", "title": "Agosto fue el mes m\u00e1s c\u00e1lido: Conagua", "author": "Chiapas Hoy//MdR", "text": "En la Ciudad de M\u00e9xico tambi\u00e9n hubo altas temperaturas con nuevos r\u00e9cords del 14 al 18 de agosto, superando los valores previos de esos d\u00edas\nLa Comisi\u00f3n Nacional del Agua (Conagua) inform\u00f3 que en agosto de 2019 se rompieron r\u00e9cords de temperatura en M\u00e9xico.Detall\u00f3 que la temperatura media observada en agosto de 2019 fue de 27.0 grados Celsius (\u00b0C), mientras que el promedio climatol\u00f3gico para dicho mes es de 23.7\u00b0C, lo que represent\u00f3 una diferencia de 3.3\u00b0C por arriba del promedio (1981-2010). El r\u00e9cord anterior del agosto m\u00e1s c\u00e1lido fue de 2015, de 26.4 \u00b0C.De los diez agostos con temperatura mayor que el promedio del periodo 1953-2019, seis corresponden a esta d\u00e9cada y los tres restantes se remontan a los 50.Las entidades que registraron su agosto m\u00e1s c\u00e1lido fueron: la Ciudad de M\u00e9xico, con 19.8\u00b0C; Coahuila, con 30.5\u00b0C; Chiapas, con 26.7\u00b0C; Durango, con 23.9\u00b0C; Hidalgo, con 21.3\u00b0C; Nuevo Le\u00f3n, con 29.8\u00b0C; Quer\u00e9taro, con 23.3\u00b0C; Quintana Roo, con 30.4\u00b0C; San Luis Potos\u00ed, con 29.0\u00b0C; Tabasco, con 29.8\u00b0C; Tamaulipas, con 31.6\u00b0C, y Yucat\u00e1n, con 29.2\u00b0C.Algunos r\u00e9cords de temperatura que se rompieron durante agosto de 2019 se registraron en los municipios de Eduardo Neri, Guerrero, con 47.5\u00b0C el 3 de agosto, lo que super\u00f3 a su m\u00e1ximo hist\u00f3rico de 47.0\u00b0C del 31 de agosto de 2017, as\u00ed como Aldama, Chihuahua, con 45.0\u00b0C, del 6 de agosto, superando su m\u00e1ximo hist\u00f3rico de 44.0\u00b0C del 14 de agosto de 1976.En la Ciudad de M\u00e9xico tambi\u00e9n hubo altas temperaturas con nuevos r\u00e9cords del 14 al 18 de agosto, superando los valores previos de esos d\u00edas: 28.2\u00b0C el d\u00eda 14, 28.3\u00b0C el 15, 28.6\u00b0C el 16, 27.9\u00b0C el 17 y 27.7\u00b0C el 18.La Conagua destac\u00f3 que un factor a considerar en el clima del pa\u00eds durante este a\u00f1o han sido las bajas precipitaciones. La lluvia acumulada del 1 de enero al 1 de septiembre en 2019 fue de 384.1 mil\u00edmetros a nivel nacional, mientras que la climatolog\u00eda del mismo per\u00edodo es de 493.5 mm (medido en litros por metro cuadrado), lo que significa que ha llovido s\u00f3lo 78% de precipitaci\u00f3n de lo que normalmente llueve.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/mexicohoy/agosto-fue-el-mes-mas-calido-conagua/"},
{"date": "2019/09/17", "topic": "M\u00e9xicoHoy", "title": "Defiende Padierna propuesta de cobrar impuesto a ventas por cat\u00e1logo", "author": "Chiapas Hoy//MdR", "text": "La propuesta del Ejecutivo Federal, de integrar a la formalidad a los vendedores por cat\u00e1logo con un esquema tributario especial para quienes se dedican a esa labor de manera independiente, dar\u00e1 certidumbre tributaria no solo al vendedor, sino a la hacienda p\u00fablica, manifest\u00f3 la vicepresidenta de la Mesa Directiva de la C\u00e1mara de Diputados, Dolores Padierna.La legisladora del Movimiento de Regeneraci\u00f3n Nacional (MORENA), dijo que el esquema simplificado de retenci\u00f3n de impuestos no afectar\u00eda las ganancias, que son m\u00ednimas, de las aproximadamente dos mil 500 personas que venden por cat\u00e1logo, sino que les permitir\u00e1 pagar impuestos de manera sencilla.\u201cEstos contribuyentes deben contar con un esquema que facilite el cumplimiento fiscal y reduzca la varga administrativa de este sector. Ello beneficiar\u00eda a 2.5 millones de personas que se dedican a esa actividad comercial. Para 2020 se propone un esquema simplificado de retenci\u00f3n que consiste en determinar el Impuesto Sobre la Renta a pagar, entre la diferencia del precio de compra del vendedor independiente, al precio en que vende su producto\u201d, explic\u00f3.\n\u201cCon esa facilidad se contribuye a fomentar la formalidad, y a dotar de certidumbre tributaria a los vendedores independientes, los cu\u00e1les ante la falta de un esquema acorde a sus necesidades, se ven obligados a tributar en el r\u00e9gimen general de personas f\u00edsicas con actividad empresarial, que es una carga muy pesada para ellos que ganan poquito. Esta medida va a crear un esquema tributario especial para vendedores independientes\u201d, insisti\u00f3.Padierna Luna remarc\u00f3 que todos los contribuyentes deben pagar sin falta sus impuestos y al establecer el cobro de ISR a vendedores y vendedoras por cat\u00e1logo, no se afectan sus escasas ganancias.Al respecto, la diputada del Partido de la Revoluci\u00f3n Democr\u00e1tica (PRD), M\u00f3nica Almeida, consider\u00f3 que ese tipo de propuestas y otros elementos del paquete econ\u00f3mico para el a\u00f1o 2020, lejos de favorecer la din\u00e1mica econ\u00f3mica, la limitar\u00e1n.Agreg\u00f3 que las disposiciones previstas para estados y municipios y la continuidad en la pol\u00edtica de austeridad, no fortalecer\u00e1n las finanzas p\u00fablicas, por el contrario, frenar\u00e1n el crecimiento.\u201cComprendemos que la administraci\u00f3n actual del pa\u00eds est\u00e9 trabajando para tener un gobierno austero. Sin embargo, hasta ahora sus acciones, m\u00e1s que impulsar la econom\u00eda tanto del pa\u00eds como de las entidades federativas, las est\u00e1 deteniendo. Por ello invito al Gobierno Federal a invertir la pir\u00e1mide de prioridades y contemplar que son los municipios los que tienen las mejores soluciones a los problemas que les aquejan, pues ellos las viven d\u00eda con d\u00eda, pero para ejecutarlas se necesitan de dinero para despu\u00e9s dinamizar su econom\u00eda y as\u00ed la del pa\u00eds\u201d, recalc\u00f3 la diputada Almeida L\u00f3pez.\nChiapas Hoy//MdR", "url": "http://www.chiapashoy.com.mx/notashoy/mexicohoy/defiende-padierna-propuesta-de-cobrar-impuesto-a-ventas-por-catalogo/"}]
\ No newline at end of file
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class NoticiasItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
text = scrapy.Field()
date = scrapy.Field()
location = scrapy.Field()
author = scrapy.Field()
topic = scrapy.Field()
url = scrapy.Field()
# -*- coding: utf-8 -*-
# Define here the models for your spider middleware
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/spider-middleware.html
from scrapy import signals
class ChiapashoySpiderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the spider middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_spider_input(response, spider):
# Called for each response that goes through the spider
# middleware and into the spider.
# Should return None or raise an exception.
return None
def process_spider_output(response, result, spider):
# Called with the results returned from the Spider, after
# it has processed the response.
# Must return an iterable of Request, dict or Item objects.
for i in result:
yield i
def process_spider_exception(response, exception, spider):
# Called when a spider or process_spider_input() method
# (from other spider middleware) raises an exception.
# Should return either None or an iterable of Response, dict
# or Item objects.
pass
def process_start_requests(start_requests, spider):
# Called with the start requests of the spider, and works
# similarly to the process_spider_output() method, except
# that it doesn’t have a response associated.
# Must return only requests (not items).
for r in start_requests:
yield r
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
import json
from collections import OrderedDict
class JsonWriterPipeline(object):
def __init__(self, filename):
self.filename = filename
@classmethod
def from_crawler(cls, crawler):
# Here you get whatever value was passed through the "filename" command line parameter
settings = crawler.settings
filename = settings.get('filename')
# Instantiate the pipeline with the file name
return cls(filename)
def open_spider(self, spider):
self.counter = 0
self.file = open(self.filename, 'w')
self.file.write("[")
def close_spider(self, spider):
self.file.write("]")
self.file.close()
def process_item(self, item, spider):
# print("this is my item", item)
row = []
try:
row.append(("date", item['date']))
except:
pass
try:
row.append(("topic", item['topic']))
except:
pass
try:
row.append(("title", item['title']))
except:
pass
try:
row.append(("author", item['author']))
except:
pass
try:
row.append(("location", item['location']))
except:
pass
try:
row.append(("text", item['text']))
except:
pass
try:
row.append(("url", item['url']))
except:
pass
line = OrderedDict(row)
self.counter += 1
if self.counter == 1:
self.file.write(json.dumps(line))
elif self.counter > 1:
self.file.write(",\n" + json.dumps(line))
return item
# -*- coding: utf-8 -*-
# Scrapy settings for chiapasHoy project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
# http://doc.scrapy.org/en/latest/topics/settings.html
# http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
# http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html
BOT_NAME = 'chiapasHoy'
SPIDER_MODULES = ['chiapasHoy.spiders']
NEWSPIDER_MODULE = 'chiapasHoy.spiders'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'chiapasHoy (+http://www.yourdomain.com)'
# Obey robots.txt rules
# ROBOTSTXT_OBEY = True
# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32
# Configure a delay for requests for the same website (default: 0)
# See http://scrapy.readthedocs.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.5
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16
# Disable cookies (enabled by default)
COOKIES_ENABLED = False
# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False
# Override the default request headers:
#DEFAULT_REQUEST_HEADERS = {
# 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
# 'Accept-Language': 'en',
#}
# Enable or disable spider middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
# 'chiapasHoy.middlewares.ChiapashoySpiderMiddleware': 543,
#}
# Enable or disable downloader middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
# 'chiapasHoy.middlewares.MyCustomDownloaderMiddleware': 543,
#}
# Enable or disable extensions
# See http://scrapy.readthedocs.org/en/latest/topics/extensions.html
#EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None,
#}
# Configure item pipelines
# See http://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'chiapasHoy.pipelines.JsonWriterPipeline': 300,
}
# Enable and configure the AutoThrottle extension (disabled by default)
# See http://doc.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True
# The initial download delay
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False
# Enable and configure HTTP caching (disabled by default)
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
# This package will contain the spiders of your Scrapy project
#
# Please refer to the documentation for information on how to create and manage
# your spiders.
# -*- coding: utf-8 -*-
import scrapy, re
from chiapasHoy.items import NoticiasItem
import datetime
"""
MEDIO:
Chiapas Hoy, Chiapas
USO:
scrapy crawl noticias --nolog -s filename=2018-01-25.json -a year=2018 -a month=1 -a day=25
"""
TAG_RE = re.compile(r'<[^>]+>')
def remove_tags(text):
return TAG_RE.sub('', text)
LOC_RE = re.compile(r'\A.+?(\d{1,2}[\s-][a-zA-Z]+[\s-]\d{4})?\s?\.\s?-\s?')
DAT_RE = re.compile(r'[,;]?(\sa?\s?\d{1,2}\sde\s[a-zA-Z]+\sde\s\d{4}\s?)?\.\s?-\s?')
class QuotesSpider(scrapy.Spider):
name = "noticias"
def start_requests(self):
year = getattr(self, "year", None)
month = getattr(self, "month", None)
day = getattr(self, "day", None)
date = datetime.date(int(year), int(month), int(day))
self.baseURL = "http://www.chiapashoy.com.mx/notashoy/" + year + "/" + month.zfill(2) + "/" + day.zfill(2)
yield scrapy.Request(url=self.baseURL, callback=self.parse, cb_kwargs={"date":date})
def parse(self, response, **kwargs):
links = response.css('article').css('h3').css('a::attr(href)').extract()
print(links)
for link in links:
yield scrapy.Request(url=link, callback=self.parse_item, cb_kwargs=kwargs)
nextPage = response.xpath('//*[@class="nav-links"]/a[@class="next page-numbers"]/@href').extract_first()
if nextPage is not None and nextPage != '':
yield scrapy.Request(url=nextPage, callback=self.parse, cb_kwargs=kwargs)
def parse_item(self, response, **kwargs):
item = NoticiasItem()
text = ''
item['date'] = kwargs["date"].strftime('%Y/%m/%d') #response.xpath('//span[@class="meta-date"]/a/time/@datetime').extract_first()
item['title'] = response.css("h1.entry-title::text").extract_first()
item['topic'] = response.css('li.meta-category').css('a::text').extract_first().replace(" ", "").replace("\n", "")
paragraphs = response.css("article").css("div.entry-content").css("p").extract()
item['author'] = remove_tags(paragraphs[-1])
text = ""
for p in paragraphs:
text += remove_tags(p) + "\n"
item['text'] = text.strip()
item['url'] = response.url
print(item)
yield item
# Automatically created by: scrapy startproject
#
# For more information about the [deploy] section see:
# https://scrapyd.readthedocs.org/en/latest/deploy.html
[settings]
default = chiapasHoy.settings
[deploy]
#url = http://localhost:6800/
project = chiapasHoy
# -*- coding: utf-8 -*-
# Define here the models for your scraped items # Define here the models for your scraped items
# #
# See documentation in: # See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html # https://docs.scrapy.org/en/latest/topics/items.html
import scrapy import scrapy
class NoticiasItem(scrapy.Item): class CuartopoderItem(scrapy.Item):
# define the fields for your item here like: # define the fields for your item here like:
# name = scrapy.Field() # name = scrapy.Field()
date = scrapy.Field()
title = scrapy.Field() title = scrapy.Field()
text = scrapy.Field() text = scrapy.Field()
date = scrapy.Field()
location = scrapy.Field() location = scrapy.Field()
author = scrapy.Field() author = scrapy.Field()
topic = scrapy.Field() topic = scrapy.Field()
......
# -*- coding: utf-8 -*-
# Define here the models for your spider middleware # Define here the models for your spider middleware
# #
# See documentation in: # See documentation in:
# https://doc.scrapy.org/en/latest/topics/spider-middleware.html # https://docs.scrapy.org/en/latest/topics/spider-middleware.html
from scrapy import signals from scrapy import signals
# useful for handling different item types with a single interface
from itemadapter import is_item, ItemAdapter
class CuartopoderSpiderMiddleware(object): class CuartopoderSpiderMiddleware:
# Not all methods need to be defined. If a method is not defined, # Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the spider middleware does not modify the # scrapy acts as if the spider middleware does not modify the
# passed objects. # passed objects.
...@@ -31,7 +32,7 @@ class CuartopoderSpiderMiddleware(object): ...@@ -31,7 +32,7 @@ class CuartopoderSpiderMiddleware(object):
# Called with the results returned from the Spider, after # Called with the results returned from the Spider, after
# it has processed the response. # it has processed the response.
# Must return an iterable of Request, dict or Item objects. # Must return an iterable of Request, or item objects.
for i in result: for i in result:
yield i yield i
...@@ -39,8 +40,7 @@ class CuartopoderSpiderMiddleware(object): ...@@ -39,8 +40,7 @@ class CuartopoderSpiderMiddleware(object):
# Called when a spider or process_spider_input() method # Called when a spider or process_spider_input() method
# (from other spider middleware) raises an exception. # (from other spider middleware) raises an exception.
# Should return either None or an iterable of Response, dict # Should return either None or an iterable of Request or item objects.
# or Item objects.
pass pass
def process_start_requests(self, start_requests, spider): def process_start_requests(self, start_requests, spider):
...@@ -56,7 +56,7 @@ class CuartopoderSpiderMiddleware(object): ...@@ -56,7 +56,7 @@ class CuartopoderSpiderMiddleware(object):
spider.logger.info('Spider opened: %s' % spider.name) spider.logger.info('Spider opened: %s' % spider.name)
class CuartopoderDownloaderMiddleware(object): class CuartopoderDownloaderMiddleware:
# Not all methods need to be defined. If a method is not defined, # Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the downloader middleware does not modify the # scrapy acts as if the downloader middleware does not modify the
# passed objects. # passed objects.
......
# -*- coding: utf-8 -*-
# Define your item pipelines here # Define your item pipelines here
# #
# Don't forget to add your pipeline to the ITEM_PIPELINES setting # Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
import json
from collections import OrderedDict
class JsonWriterPipeline(object):
def __init__(self, filename):
self.filename = filename
@classmethod
def from_crawler(cls, crawler):
# Here you get whatever value was passed through the "filename" command line parameter
settings = crawler.settings
filename = settings.get('filename')
# Instantiate the pipeline with the file name # useful for handling different item types with a single interface
return cls(filename) from itemadapter import ItemAdapter
def open_spider(self, spider):
self.counter = 0
self.file = open(self.filename, 'w')
self.file.write("[")
def close_spider(self, spider):
self.file.write("]")
self.file.close()
class CuartopoderPipeline:
def process_item(self, item, spider): def process_item(self, item, spider):
# print("this is my item", item)
row = []
try:
row.append(("date", item['date']))
except:
pass
try:
row.append(("topic", item['topic']))
except:
pass
try:
row.append(("title", item['title']))
except:
pass
try:
row.append(("author", item['author']))
except:
pass
try:
row.append(("location", item['location']))
except:
pass
try:
row.append(("text", item['text']))
except:
pass
try:
row.append(("url", item['url']))
except:
pass
line = OrderedDict(row)
self.counter += 1
if self.counter == 1:
self.file.write(json.dumps(line))
elif self.counter > 1:
self.file.write(",\n" + json.dumps(line))
return item return item
# -*- coding: utf-8 -*-
# Scrapy settings for cuartoPoder project # Scrapy settings for cuartoPoder project
# #
# For simplicity, this file contains only settings considered important or # For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation: # commonly used. You can find more settings consulting the documentation:
# #
# https://doc.scrapy.org/en/latest/topics/settings.html # https://docs.scrapy.org/en/latest/topics/settings.html
# https://doc.scrapy.org/en/latest/topics/downloader-middleware.html # https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
# https://doc.scrapy.org/en/latest/topics/spider-middleware.html # https://docs.scrapy.org/en/latest/topics/spider-middleware.html
BOT_NAME = 'cuartoPoder' BOT_NAME = 'cuartoPoder'
SPIDER_MODULES = ['cuartoPoder.spiders'] SPIDER_MODULES = ['cuartoPoder.spiders']
NEWSPIDER_MODULE = 'cuartoPoder.spiders' NEWSPIDER_MODULE = 'cuartoPoder.spiders'
FEED_EXPORT_ENCODING="utf-8"
# Crawl responsibly by identifying yourself (and your website) on the user-agent # Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'cuartoPoder (+http://www.yourdomain.com)' #USER_AGENT = 'cuartoPoder (+http://www.yourdomain.com)'
# Obey robots.txt rules # Obey robots.txt rules
# ROBOTSTXT_OBEY = True ROBOTSTXT_OBEY = True
# Configure maximum concurrent requests performed by Scrapy (default: 16) # Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32 #CONCURRENT_REQUESTS = 32
# Configure a delay for requests for the same website (default: 0) # Configure a delay for requests for the same website (default: 0)
# See https://doc.scrapy.org/en/latest/topics/settings.html#download-delay # See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs # See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.5 #DOWNLOAD_DELAY = 3
# The download delay setting will honor only one of: # The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16 #CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16 #CONCURRENT_REQUESTS_PER_IP = 16
# Disable cookies (enabled by default) # Disable cookies (enabled by default)
COOKIES_ENABLED = False #COOKIES_ENABLED = False
# Disable Telnet Console (enabled by default) # Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False #TELNETCONSOLE_ENABLED = False
...@@ -45,31 +43,31 @@ COOKIES_ENABLED = False ...@@ -45,31 +43,31 @@ COOKIES_ENABLED = False
#} #}
# Enable or disable spider middlewares # Enable or disable spider middlewares
# See https://doc.scrapy.org/en/latest/topics/spider-middleware.html # See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = { #SPIDER_MIDDLEWARES = {
# 'cuartoPoder.middlewares.CuartopoderSpiderMiddleware': 543, # 'cuartoPoder.middlewares.CuartopoderSpiderMiddleware': 543,
#} #}
# Enable or disable downloader middlewares # Enable or disable downloader middlewares
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html # See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = { #DOWNLOADER_MIDDLEWARES = {
# 'cuartoPoder.middlewares.CuartopoderDownloaderMiddleware': 543, # 'cuartoPoder.middlewares.CuartopoderDownloaderMiddleware': 543,
#} #}
# Enable or disable extensions # Enable or disable extensions
# See https://doc.scrapy.org/en/latest/topics/extensions.html # See https://docs.scrapy.org/en/latest/topics/extensions.html
#EXTENSIONS = { #EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None, # 'scrapy.extensions.telnet.TelnetConsole': None,
#} #}
# Configure item pipelines # Configure item pipelines
# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html # See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = { #ITEM_PIPELINES = {
'cuartoPoder.pipelines.JsonWriterPipeline': 300, # 'cuartoPoder.pipelines.CuartopoderPipeline': 300,
} #}
# Enable and configure the AutoThrottle extension (disabled by default) # Enable and configure the AutoThrottle extension (disabled by default)
# See https://doc.scrapy.org/en/latest/topics/autothrottle.html # See https://docs.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True #AUTOTHROTTLE_ENABLED = True
# The initial download delay # The initial download delay
#AUTOTHROTTLE_START_DELAY = 5 #AUTOTHROTTLE_START_DELAY = 5
...@@ -82,7 +80,7 @@ ITEM_PIPELINES = { ...@@ -82,7 +80,7 @@ ITEM_PIPELINES = {
#AUTOTHROTTLE_DEBUG = False #AUTOTHROTTLE_DEBUG = False
# Enable and configure HTTP caching (disabled by default) # Enable and configure HTTP caching (disabled by default)
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings # See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True #HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0 #HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache' #HTTPCACHE_DIR = 'httpcache'
......
# -*- coding: utf-8 -*- import scrapy
import json
""" import datetime
MEDIA: from cuartoPoder.items import CuartopoderItem
Cuarto Poder, Chiapas #-------------------------------------------------------------------------------
import re
USAGE:
## Get all the news from a specific date. ##
---------------------------------------------------------------------------------------------
$ cd cuartoPoder/
$ scrapy crawl noticias --nolog -s filename=2018-08-30.json -a year=2018 -a month=8 -a day=30
"""
import scrapy, re
from cuartoPoder.items import NoticiasItem
from datetime import datetime, date, timedelta, tzinfo
TAG_RE = re.compile(r'<[^>]+>') TAG_RE = re.compile(r'<[^>]+>')
def remove_tags(text): def remove_tags(text):
return TAG_RE.sub('', text) return TAG_RE.sub('', text)
#-------------------------------------------------------------------------------
class NoticiasSpider(scrapy.Spider):
name = 'noticias'
allowed_domains = ['cuartopoder.mx']
start_urls = ['https://cuartopoder.mx/']
#-----------------------------------------------------------------------
class UTC(tzinfo):
"""
Class for Time Zone
"""
def utcoffset(self, dt):
## Time zone for Chiapas: UTC-6 ##
return timedelta(hours=-6)
def tzname(self, dt):
## Time zone name ##
return 'UTC-6'
class ImportantData(scrapy.Item):
"""
Useful data for the flow of the implementation
"""
to_next_page = scrapy.Field()
is_last_link = scrapy.Field()
next_page = scrapy.Field()
return_url = scrapy.Field()
class QuotesSpider(scrapy.Spider):
"""
Basic Scrapy Spider class
"""
name = "noticias"
def start_requests(self): def start_requests(self):
self.tz = UTC()
self.year = getattr(self, "year", None) self.year = getattr(self, "year", None)
self.month = getattr(self, "month", None) self.month = getattr(self, "month", None)
self.day = getattr(self, "day", None) self.day = getattr(self, "day", None)
self.stop_date = date(int(self.year), int(self.month), int(self.day)) date = self.month.zfill(2)+"-"+self.day.zfill(2)+"-"+self.year
print(date)
self.baseURL = "http://www.cuartopoder.mx" url = self.start_urls[0]+"XStatic/cuartopoder/template/cargaBloque.aspx?strControl=ctrlArchivoResultadosPaginadoListado&eids=&fd="+date+"&fh="+date+"&id=portada&p=1"
first_URL = self.baseURL + "/archivo/portada/listado/{1}-{2}-{0}/{1}-{2}-{0}/".format(self.year, self.month.zfill(2), self.day.zfill(2)) yield scrapy.Request(url=url, callback=self.parsePage)
self.second_URL = self.baseURL + "/XStatic/cuartopoder/template/cargaBloque.aspx?strControl=ctrlArchivoResultadosPaginadoListado&" #-----------------------------------------------------------------------
def parsePage(self, response):
self.month_parser = {"Enero" : 1, "Mayo" : 5, "Septiembre" : 9, i = response.url.index("&p=")
"Febrero" : 2, "Junio" : 6, "Octubre" : 10, url = response.url[:i+3]+str(int(response.url[i+3:])+1)
"Marzo" : 3, "Julio" : 7, "Noviembre" : 11, links = response.css('ul.news-list').xpath('./li/h5/a/@href').extract()
"Abril" : 4, "Agosto" : 8, "Diciembre" : 12} print(response.url)
print(len(links))
flow_info = ImportantData() if len(links)>0:
flow_info['to_next_page'] = False for l in links:
flow_info['next_page'] = 2 yield scrapy.Request(url=self.start_urls[0][:-1]+l, callback=self.parse)
yield scrapy.Request(url=url, callback=self.parsePage)
request = scrapy.Request(url=first_URL, callback=self.parse) #-----------------------------------------------------------------------
request.meta['item'] = flow_info
yield request
def parse(self, response): def parse(self, response):
flow_info = response.meta['item'] item = CuartopoderItem()
page = flow_info['next_page']
date = self.year+"-"+self.month.zfill(2)+"-"+self.day.zfill(2)
if not flow_info['to_next_page']: item["date"]= datetime.datetime.strptime(date, '%Y-%m-%d').isoformat()
link_list = response.css('ul.news-list').xpath('./li/h5/a/@href').extract() item["title"] =response.xpath("//meta[@property='og:title']/@content").extract_first()
item["topic"] = response.css('div.big-title').xpath('./h2/a/span//text()').extract_first()
for link in link_list: item["text"] =response.xpath("//meta[@name='Description']/@content").extract_first()
flow_info = ImportantData() item["url"] = response.url
flow_info['next_page'] = page print(item["title"])
flow_info['return_url'] = response.url
if link == link_list[-1] : flow_info['is_last_link'] = True
else : flow_info['is_last_link'] = False
news_link = self.baseURL + link
request = scrapy.Request(url=news_link, callback=self.parse_item)
request.meta['item'] = flow_info
yield request
else:
page_URL = self.second_URL + "p={3}&eids=&fd={1}-{2}-{0}&fh={1}-{2}-{0}&id=portada".format(self.year, self.month.zfill(2), self.day.zfill(2), str(page))
flow_info['to_next_page'] = False
flow_info['next_page'] += 1
request = scrapy.Request(url=page_URL, callback=self.parse)
request.meta['item'] = flow_info
yield request
def parse_item(self, response):
news_date = response.css('ul.metas-list > li > p').extract_first()
news_date = remove_tags(news_date)
news_date = news_date.split(u'\xa0')
news_date[1] = news_date[1].strip().replace(",", '')
news_date = date(int(self.year), self.month_parser[news_date[0]], int(news_date[1]))
if news_date == self.stop_date:
flow_info = response.meta['item']
item = NoticiasItem()
text = ''
news_date = datetime(int(self.year), int(self.month), int(self.day), tzinfo=self.tz).isoformat("T")
title = response.css('div.post-title').css('h1').extract_first()
if title is not None : title = remove_tags(title)
topic = response.css('div.big-title').xpath('./h2/a/span').extract_first()
if topic is not None : topic = remove_tags(topic)
for p in response.css('div.post-content').css('p').extract():
p = remove_tags(p)
text += p + "\n"
## News item info ##
item['date'] = news_date
item['title'] = title.strip()
item['topic'] = topic
item['text'] = text.strip()
item['url'] = response.url
yield item yield item
if flow_info['is_last_link']:
flow_info['to_next_page'] = True
request = scrapy.Request(url=flow_info['return_url'], callback=self.parse, dont_filter=True)
request.meta['item'] = flow_info
yield request
\ No newline at end of file
...@@ -41,6 +41,7 @@ class QuotesSpider(scrapy.Spider): ...@@ -41,6 +41,7 @@ class QuotesSpider(scrapy.Spider):
def parse(self, response): def parse(self, response):
print(response.url)
yield scrapy.Request(url=response.url, callback=self.parse_page, dont_filter=True) yield scrapy.Request(url=response.url, callback=self.parse_page, dont_filter=True)
pagination = response.xpath('//*[@class="pagination"]/a[@class="page-numbers"]/@href').extract() pagination = response.xpath('//*[@class="pagination"]/a[@class="page-numbers"]/@href').extract()
...@@ -78,6 +79,6 @@ class QuotesSpider(scrapy.Spider): ...@@ -78,6 +79,6 @@ class QuotesSpider(scrapy.Spider):
item['url'] = response.url item['url'] = response.url
# print item['title'] print (item['title'])
yield item yield item
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class NoticiasItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
text = scrapy.Field()
date = scrapy.Field()
location = scrapy.Field()
author = scrapy.Field()
topic = scrapy.Field()
url = scrapy.Field()
# -*- coding: utf-8 -*-
# Define here the models for your spider middleware
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/spider-middleware.html
from scrapy import signals
class DespertaroaxacaSpiderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the spider middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_spider_input(response, spider):
# Called for each response that goes through the spider
# middleware and into the spider.
# Should return None or raise an exception.
return None
def process_spider_output(response, result, spider):
# Called with the results returned from the Spider, after
# it has processed the response.
# Must return an iterable of Request, dict or Item objects.
for i in result:
yield i
def process_spider_exception(response, exception, spider):
# Called when a spider or process_spider_input() method
# (from other spider middleware) raises an exception.
# Should return either None or an iterable of Response, dict
# or Item objects.
pass
def process_start_requests(start_requests, spider):
# Called with the start requests of the spider, and works
# similarly to the process_spider_output() method, except
# that it doesn’t have a response associated.
# Must return only requests (not items).
for r in start_requests:
yield r
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
import json
from collections import OrderedDict
class JsonWriterPipeline(object):
def __init__(self, filename):
self.filename = filename
@classmethod
def from_crawler(cls, crawler):
# Here you get whatever value was passed through the "filename" command line parameter
settings = crawler.settings
filename = settings.get('filename')
# Instantiate the pipeline with the file name
return cls(filename)
def open_spider(self, spider):
self.counter = 0
self.file = open(self.filename, 'w')
self.file.write("[")
def close_spider(self, spider):
self.file.write("]")
self.file.close()
def process_item(self, item, spider):
# print("this is my item", item)
row = []
try:
row.append(("date", item['date']))
except:
pass
try:
row.append(("topic", item['topic']))
except:
pass
try:
row.append(("title", item['title']))
except:
pass
try:
row.append(("author", item['author']))
except:
pass
try:
row.append(("location", item['location']))
except:
pass
try:
row.append(("text", item['text']))
except:
pass
try:
row.append(("url", item['url']))
except:
pass
line = OrderedDict(row)
self.counter += 1
if self.counter == 1:
self.file.write(json.dumps(line))
elif self.counter > 1:
self.file.write(",\n" + json.dumps(line))
return item
# -*- coding: utf-8 -*-
# Scrapy settings for despertarOaxaca project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
# http://doc.scrapy.org/en/latest/topics/settings.html
# http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
# http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html
BOT_NAME = 'despertarOaxaca'
SPIDER_MODULES = ['despertarOaxaca.spiders']
NEWSPIDER_MODULE = 'despertarOaxaca.spiders'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'despertarOaxaca (+http://www.yourdomain.com)'
# Obey robots.txt rules
# ROBOTSTXT_OBEY = True
# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32
# Configure a delay for requests for the same website (default: 0)
# See http://scrapy.readthedocs.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.5
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16
# Disable cookies (enabled by default)
COOKIES_ENABLED = False
# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False
# Override the default request headers:
#DEFAULT_REQUEST_HEADERS = {
# 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
# 'Accept-Language': 'en',
#}
# Enable or disable spider middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
# 'despertarOaxaca.middlewares.DespertaroaxacaSpiderMiddleware': 543,
#}
# Enable or disable downloader middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
# 'despertarOaxaca.middlewares.MyCustomDownloaderMiddleware': 543,
#}
# Enable or disable extensions
# See http://scrapy.readthedocs.org/en/latest/topics/extensions.html
#EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None,
#}
# Configure item pipelines
# See http://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'despertarOaxaca.pipelines.JsonWriterPipeline': 300,
}
# Enable and configure the AutoThrottle extension (disabled by default)
# See http://doc.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True
# The initial download delay
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False
# Enable and configure HTTP caching (disabled by default)
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
# This package will contain the spiders of your Scrapy project
#
# Please refer to the documentation for information on how to create and manage
# your spiders.
# -*- coding: utf-8 -*-
import scrapy, re
from despertarOaxaca.items import NoticiasItem
"""
MEDIO:
El Despertar de Oaxaca
USO:
scrapy crawl noticias --nolog -s filename=2018-02-04.json -a year=2018 -a month=2 -a day=4
"""
TAG_RE = re.compile(r'<[^>]+>')
def remove_tags(text):
return TAG_RE.sub('', text)
# LOC_RE = re.compile(r'\n.+?,? ?.+? ?\. ?- ?')
# G_RE = re.compile(r' ?- ?')
# EM_RE = re.compile(r'((Email|Correo electr.{1,3}nico|Comentarios?):\s)?[\w.-]+@[\w-]+(\.[a-zA-Z]{2,6}){1,2}\s?')
# TW_RE = re.compile(r'M.{1,3}s de la P.{1,3}lvora en Twitter: @[\w.%+-]+.', re.I)
# TW2_RE = re.compile(r'((\| )?Twitter:\s+)?(@[\w.%+-]+.)?', re.I)
# TAG2_RE = re.compile(r'\ntransition_[^\]]+\]')
# TAG3_RE = re.compile(r'\[[^\]]+[\]\n]')
class QuotesSpider(scrapy.Spider):
name = "noticias"
def start_requests(self):
year = getattr(self, "year", None)
month = getattr(self, "month", None)
day = getattr(self, "day", None)
self.baseURL = "http://despertardeoaxaca.com/" + year + "/" + month.zfill(2) + "/" + day.zfill(2)
yield scrapy.Request(url=self.baseURL, callback=self.parse)
def parse(self, response):
yield scrapy.Request(url=response.url, callback=self.parse_page, dont_filter=True)
pagination = response.xpath('//div[@class="post-pagination cat-"]/a/@href').extract()
if len(pagination) > 0:
pagination = pagination[-1].strip('/')
pages = int(pagination[pagination.rfind('/') + 1:])
for page in range(1, pages):
yield scrapy.Request(url=self.baseURL + '/page/' + str(page + 1), callback=self.parse_page)
def parse_page(self, response):
for post in response.xpath('//div[@class="articles"]').css('div.cnt'):
item = NoticiasItem()
topic = post.css('span.category').xpath('./a').extract_first()
if topic is not None:
item['topic'] = remove_tags(topic)
link = post.css('h3').xpath('./a/@href').extract_first()
request = scrapy.Request(url=link, callback=self.parse_item)
request.meta['item'] = item
yield request
def parse_item(self, response):
item = response.meta['item']
text = ''
"La fecha obtenida ya incluye formato y zona horaria"
item['date'] = response.xpath('//meta[@property="article:published_time"]/@content').extract_first()
item['title'] = remove_tags(response.css('article.article-post').xpath('./header/h1').extract_first()).strip()
for p in response.xpath('//div[@class="article-post-content"]').css('p').extract():
text += remove_tags(p) + "\n"
# result = LOC_RE.search(text)
# if result:
# m = result.group(0)
# location = G_RE.sub('', m).strip()
# if len(location) <= 35:
# item['location'] = location
# text = text[text.find(m)+len(m):]
# text = EM_RE.sub('', text)
# text = TW_RE.sub('', text)
# text = TW2_RE.sub('', text)
# text = TAG2_RE.sub("\n", text)
# text = TAG3_RE.sub('', text)
item['text'] = text.strip()
item['url'] = response.url
yield item
# Automatically created by: scrapy startproject
#
# For more information about the [deploy] section see:
# https://scrapyd.readthedocs.org/en/latest/deploy.html
[settings]
default = despertarOaxaca.settings
[deploy]
#url = http://localhost:6800/
project = despertarOaxaca
This source diff could not be displayed because it is too large. You can view the blob instead.
File mode changed from 100755 to 100644
# -*- coding: utf-8 -*-
# Define here the models for your scraped items # Define here the models for your scraped items
# #
# See documentation in: # See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html # https://docs.scrapy.org/en/latest/topics/items.html
import scrapy import scrapy
class NoticiasItem(scrapy.Item): class EdomexdiaItem(scrapy.Item):
# define the fields for your item here like: # define the fields for your item here like:
# name = scrapy.Field() # name = scrapy.Field()
date = scrapy.Field()
title = scrapy.Field() title = scrapy.Field()
text = scrapy.Field() text = scrapy.Field()
date = scrapy.Field()
location = scrapy.Field() location = scrapy.Field()
author = scrapy.Field() author = scrapy.Field()
topic = scrapy.Field() topic = scrapy.Field()
......
# -*- coding: utf-8 -*-
# Define here the models for your spider middleware # Define here the models for your spider middleware
# #
# See documentation in: # See documentation in:
# http://doc.scrapy.org/en/latest/topics/spider-middleware.html # https://docs.scrapy.org/en/latest/topics/spider-middleware.html
from scrapy import signals from scrapy import signals
# useful for handling different item types with a single interface
from itemadapter import is_item, ItemAdapter
class EdomexdiaSpiderMiddleware(object): class EdomexdiaSpiderMiddleware:
# Not all methods need to be defined. If a method is not defined, # Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the spider middleware does not modify the # scrapy acts as if the spider middleware does not modify the
# passed objects. # passed objects.
...@@ -20,30 +21,29 @@ class EdomexdiaSpiderMiddleware(object): ...@@ -20,30 +21,29 @@ class EdomexdiaSpiderMiddleware(object):
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened) crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s return s
def process_spider_input(response, spider): def process_spider_input(self, response, spider):
# Called for each response that goes through the spider # Called for each response that goes through the spider
# middleware and into the spider. # middleware and into the spider.
# Should return None or raise an exception. # Should return None or raise an exception.
return None return None
def process_spider_output(response, result, spider): def process_spider_output(self, response, result, spider):
# Called with the results returned from the Spider, after # Called with the results returned from the Spider, after
# it has processed the response. # it has processed the response.
# Must return an iterable of Request, dict or Item objects. # Must return an iterable of Request, or item objects.
for i in result: for i in result:
yield i yield i
def process_spider_exception(response, exception, spider): def process_spider_exception(self, response, exception, spider):
# Called when a spider or process_spider_input() method # Called when a spider or process_spider_input() method
# (from other spider middleware) raises an exception. # (from other spider middleware) raises an exception.
# Should return either None or an iterable of Response, dict # Should return either None or an iterable of Request or item objects.
# or Item objects.
pass pass
def process_start_requests(start_requests, spider): def process_start_requests(self, start_requests, spider):
# Called with the start requests of the spider, and works # Called with the start requests of the spider, and works
# similarly to the process_spider_output() method, except # similarly to the process_spider_output() method, except
# that it doesn’t have a response associated. # that it doesn’t have a response associated.
...@@ -54,3 +54,50 @@ class EdomexdiaSpiderMiddleware(object): ...@@ -54,3 +54,50 @@ class EdomexdiaSpiderMiddleware(object):
def spider_opened(self, spider): def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name) spider.logger.info('Spider opened: %s' % spider.name)
class EdomexdiaDownloaderMiddleware:
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the downloader middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_request(self, request, spider):
# Called for each request that goes through the downloader
# middleware.
# Must either:
# - return None: continue processing this request
# - or return a Response object
# - or return a Request object
# - or raise IgnoreRequest: process_exception() methods of
# installed downloader middleware will be called
return None
def process_response(self, request, response, spider):
# Called with the response returned from the downloader.
# Must either;
# - return a Response object
# - return a Request object
# - or raise IgnoreRequest
return response
def process_exception(self, request, exception, spider):
# Called when a download handler or a process_request()
# (from other downloader middleware) raises an exception.
# Must either:
# - return None: continue processing this exception
# - return a Response object: stops process_exception() chain
# - return a Request object: stops process_exception() chain
pass
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
# -*- coding: utf-8 -*-
# Define your item pipelines here # Define your item pipelines here
# #
# Don't forget to add your pipeline to the ITEM_PIPELINES setting # Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
import json
from collections import OrderedDict
class JsonWriterPipeline(object):
def __init__(self, filename):
self.filename = filename
@classmethod
def from_crawler(cls, crawler):
# Here you get whatever value was passed through the "filename" command line parameter
settings = crawler.settings
filename = settings.get('filename')
# Instantiate the pipeline with the file name # useful for handling different item types with a single interface
return cls(filename) from itemadapter import ItemAdapter
def open_spider(self, spider):
self.counter = 0
self.file = open(self.filename, 'w')
self.file.write("[")
def close_spider(self, spider):
self.file.write("]")
self.file.close()
class EdomexdiaPipeline:
def process_item(self, item, spider): def process_item(self, item, spider):
# print("this is my item", item)
row = []
try:
row.append(("date", item['date']))
except:
pass
try:
row.append(("topic", item['topic']))
except:
pass
try:
row.append(("title", item['title']))
except:
pass
try:
row.append(("author", item['author']))
except:
pass
try:
row.append(("location", item['location']))
except:
pass
try:
row.append(("text", item['text']))
except:
pass
try:
row.append(("url", item['url']))
except:
pass
line = OrderedDict(row)
self.counter += 1
if self.counter == 1:
self.file.write(json.dumps(line))
elif self.counter > 1:
self.file.write(",\n" + json.dumps(line))
return item return item
# -*- coding: utf-8 -*-
# Scrapy settings for edoMexDia project # Scrapy settings for edoMexDia project
# #
# For simplicity, this file contains only settings considered important or # For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation: # commonly used. You can find more settings consulting the documentation:
# #
# http://doc.scrapy.org/en/latest/topics/settings.html # https://docs.scrapy.org/en/latest/topics/settings.html
# http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html # https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
# http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html # https://docs.scrapy.org/en/latest/topics/spider-middleware.html
BOT_NAME = 'edoMexDia' BOT_NAME = 'edoMexDia'
SPIDER_MODULES = ['edoMexDia.spiders'] SPIDER_MODULES = ['edoMexDia.spiders']
NEWSPIDER_MODULE = 'edoMexDia.spiders' NEWSPIDER_MODULE = 'edoMexDia.spiders'
FEED_EXPORT_ENCODING="utf-8"
# Crawl responsibly by identifying yourself (and your website) on the user-agent # Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'edoMexDia (+http://www.yourdomain.com)' #USER_AGENT = 'edoMexDia (+http://www.yourdomain.com)'
# Obey robots.txt rules # Obey robots.txt rules
# ROBOTSTXT_OBEY = True ROBOTSTXT_OBEY = True
# Configure maximum concurrent requests performed by Scrapy (default: 16) # Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32 #CONCURRENT_REQUESTS = 32
# Configure a delay for requests for the same website (default: 0) # Configure a delay for requests for the same website (default: 0)
# See http://scrapy.readthedocs.org/en/latest/topics/settings.html#download-delay # See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs # See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.5 #DOWNLOAD_DELAY = 3
# The download delay setting will honor only one of: # The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16 #CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16 #CONCURRENT_REQUESTS_PER_IP = 16
# Disable cookies (enabled by default) # Disable cookies (enabled by default)
COOKIES_ENABLED = False #COOKIES_ENABLED = False
# Disable Telnet Console (enabled by default) # Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False #TELNETCONSOLE_ENABLED = False
...@@ -45,31 +43,31 @@ COOKIES_ENABLED = False ...@@ -45,31 +43,31 @@ COOKIES_ENABLED = False
#} #}
# Enable or disable spider middlewares # Enable or disable spider middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html # See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = { #SPIDER_MIDDLEWARES = {
# 'edoMexDia.middlewares.EdomexdiaSpiderMiddleware': 543, # 'edoMexDia.middlewares.EdomexdiaSpiderMiddleware': 543,
#} #}
# Enable or disable downloader middlewares # Enable or disable downloader middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html # See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = { #DOWNLOADER_MIDDLEWARES = {
# 'edoMexDia.middlewares.MyCustomDownloaderMiddleware': 543, # 'edoMexDia.middlewares.EdomexdiaDownloaderMiddleware': 543,
#} #}
# Enable or disable extensions # Enable or disable extensions
# See http://scrapy.readthedocs.org/en/latest/topics/extensions.html # See https://docs.scrapy.org/en/latest/topics/extensions.html
#EXTENSIONS = { #EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None, # 'scrapy.extensions.telnet.TelnetConsole': None,
#} #}
# Configure item pipelines # Configure item pipelines
# See http://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html # See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = { #ITEM_PIPELINES = {
'edoMexDia.pipelines.JsonWriterPipeline': 300, # 'edoMexDia.pipelines.EdomexdiaPipeline': 300,
} #}
# Enable and configure the AutoThrottle extension (disabled by default) # Enable and configure the AutoThrottle extension (disabled by default)
# See http://doc.scrapy.org/en/latest/topics/autothrottle.html # See https://docs.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True #AUTOTHROTTLE_ENABLED = True
# The initial download delay # The initial download delay
#AUTOTHROTTLE_START_DELAY = 5 #AUTOTHROTTLE_START_DELAY = 5
...@@ -82,7 +80,7 @@ ITEM_PIPELINES = { ...@@ -82,7 +80,7 @@ ITEM_PIPELINES = {
#AUTOTHROTTLE_DEBUG = False #AUTOTHROTTLE_DEBUG = False
# Enable and configure HTTP caching (disabled by default) # Enable and configure HTTP caching (disabled by default)
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings # See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True #HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0 #HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache' #HTTPCACHE_DIR = 'httpcache'
......
File mode changed from 100755 to 100644
# -*- coding: utf-8 -*- """
Spider for edomexaldia.com
Author: Mario Chirinos Coluga
Usage:scrapy crawl noticias --nolog -O 2017-04-23.json -a year=2017 -a month=4 -a day=23
"""
import scrapy, re import scrapy, re
from edoMexDia.items import NoticiasItem from edoMexDia.items import EdomexdiaItem
from datetime import datetime, timedelta, tzinfo from datetime import datetime, timedelta, tzinfo
"""
MEDIO:
EDOMEX al Día, Estado de México
USO:
scrapy crawl noticias --nolog -s filename=2018-01-30.json -a year=2018 -a month=1 -a day=30
"""
TAG_RE = re.compile(r'<[^>]+>') TAG_RE = re.compile(r'<[^>]+>')
def remove_tags(text): def remove_tags(text):
return TAG_RE.sub('', text) return TAG_RE.sub('', text)
class UTC(tzinfo):
"""clase para el 'time zone' (zona horaria)"""
def utcoffset(self, dt):
# zona horaria para estado de méxico: utc-6
return timedelta(hours=-6)
def tzname(self, dt):
# nombre de la zona horaria
return 'UTC-6'
class QuotesSpider(scrapy.Spider): class QuotesSpider(scrapy.Spider):
name = "noticias" name = "noticias"
def start_requests(self): def start_requests(self):
self.tz = UTC()
self.year = getattr(self, "year", None) self.year = getattr(self, "year", None)
self.month = getattr(self, "month", None) self.month = getattr(self, "month", None)
self.day = getattr(self, "day", None) self.day = getattr(self, "day", None)
self.date_parser = {'january': 1, 'february': 2, 'march': 3, 'april': 4,
'may': 5, 'june': 6, 'july': 7, 'august': 8,
'september': 9, 'october': 10, 'november': 11, 'december': 12}
self.baseURL = "http://www.edomexaldia.com.mx/" + self.year + "/" + self.month.zfill(2) + "/" + self.day.zfill(2)
yield scrapy.Request(url=self.baseURL, callback=self.parse)
self.baseURL = "http://edomexaldia.com/" + self.year + "/" + self.month.zfill(2) + "/" + self.day.zfill(2)
def parse(self, response): yield scrapy.Request(url=self.baseURL, callback=self.parse_page)
yield scrapy.Request(url=response.url, callback=self.parse_page, dont_filter=True)
lastPage = response.xpath('//div[@class="numbered-pagination"]/a[@class="pagi-last"]/@href').extract_first()
if lastPage is None:
lastPage = response.xpath('//div[@class="numbered-pagination"]/a/@href').extract()[-1]
if lastPage is not None and lastPage != '':
lastPage = lastPage.strip('/')
lastPage = int(lastPage[lastPage.rfind('/')+1:])
for page in range(1, lastPage):
yield scrapy.Request(url=self.baseURL + "/page/" + str(page+1), callback=self.parse_page)
#-----------------------------------------------------------------------
def parse_page(self, response): def parse_page(self, response):
for link in response.xpath('//div[@id="main"]/div/h2[@class="entry_title"]/a/@href').extract(): print("parse page", response.url)
for link in response.xpath('//main[@id="main"]/article/header/h2[@class="entry-title"]/a/@href').extract():
yield scrapy.Request(url=link, callback=self.parse_item) yield scrapy.Request(url=link, callback=self.parse_item)
next = response.css('a.next::attr(href)').extract_first()
nextPage = response.xpath('//div[@class="numbered-pagination"]/a[@class="pagi-next"]/@href').extract_first() if next is not None:
if nextPage is not None and nextPage != '': yield scrapy.Request(url=next, callback=self.parse_page)
yield scrapy.Request(url=nextPage, callback=self.parse) #-----------------------------------------------------------------------
def parse_item(self, response): def parse_item(self, response):
item = NoticiasItem() item = EdomexdiaItem()
text = ''
item['date'] = response.xpath("//meta[@property='article:published_time']/@content").extract_first()
try: item['title'] = response.xpath("//meta[@property='og:title']/@content").extract_first().replace(" - Edomex Al Día","")
d = remove_tags(response.xpath('//span[@class="post_author_create"]').extract_first()) text=""
d = d.replace("el ", '').replace(",", '').replace(".", '').split() for p in response.xpath('//div[@class="entry-content"]/p/text()').extract():
dat = datetime(int(d[2]), self.date_parser[d[1].lower()], int(d[0]), tzinfo=self.tz).isoformat("T") nt = remove_tags(p).replace("\n","").replace("\r","").strip()
except: text+=nt
dat = datetime(int(self.year), int(self.month), int(self.day), tzinfo=self.tz).isoformat("T") if len(nt)>0:
item['date'] = dat text+="\n"
item['title'] = remove_tags(response.xpath('//div[@id="main"]/div/h1').extract_first()).strip()
item['topic'] = None
author = response.xpath('//span[@class="post_author_author"]').extract_first()
if author is not None and author != '':
author = remove_tags(author).strip()
author = author.replace(" Publicado:", '')
item['author'] = author
for p in response.xpath('//div[@id="main"]/div/p').extract():
text += remove_tags(p) + "\n"
item['text'] = text.strip() item['text'] = text.strip()
item['topic'] = ", ".join(response.xpath('//span[@class="tag-links"]/a/text()').extract())
item['url'] = response.url item['url'] = response.url
item["author"]=""
item["location"]=""
print(item["url"])
yield item yield item
# Automatically created by: scrapy startproject # Automatically created by: scrapy startproject
# #
# For more information about the [deploy] section see: # For more information about the [deploy] section see:
# https://scrapyd.readthedocs.org/en/latest/deploy.html # https://scrapyd.readthedocs.io/en/latest/deploy.html
[settings] [settings]
default = edoMexDia.settings default = edoMexDia.settings
......
# -*- coding: utf-8 -*-
# Define here the models for your scraped items # Define here the models for your scraped items
# #
# See documentation in: # See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html # https://docs.scrapy.org/en/latest/topics/items.html
import scrapy import scrapy
...@@ -11,14 +9,12 @@ import scrapy ...@@ -11,14 +9,12 @@ import scrapy
class ElfinancieroItem(scrapy.Item): class ElfinancieroItem(scrapy.Item):
# define the fields for your item here like: # define the fields for your item here like:
# name = scrapy.Field() # name = scrapy.Field()
pass date = scrapy.Field()
class NoticiasItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field() title = scrapy.Field()
text = scrapy.Field() text = scrapy.Field()
date = scrapy.Field()
location = scrapy.Field() location = scrapy.Field()
author = scrapy.Field() author = scrapy.Field()
topic = scrapy.Field() topic = scrapy.Field()
url = scrapy.Field() url = scrapy.Field()
media = scrapy.Field()
# -*- coding: utf-8 -*-
# Define here the models for your spider middleware # Define here the models for your spider middleware
# #
# See documentation in: # See documentation in:
# https://doc.scrapy.org/en/latest/topics/spider-middleware.html # https://docs.scrapy.org/en/latest/topics/spider-middleware.html
from scrapy import signals from scrapy import signals
# useful for handling different item types with a single interface
from itemadapter import is_item, ItemAdapter
class ElfinancieroSpiderMiddleware(object): class ElfinancieroSpiderMiddleware:
# Not all methods need to be defined. If a method is not defined, # Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the spider middleware does not modify the # scrapy acts as if the spider middleware does not modify the
# passed objects. # passed objects.
...@@ -31,7 +32,7 @@ class ElfinancieroSpiderMiddleware(object): ...@@ -31,7 +32,7 @@ class ElfinancieroSpiderMiddleware(object):
# Called with the results returned from the Spider, after # Called with the results returned from the Spider, after
# it has processed the response. # it has processed the response.
# Must return an iterable of Request, dict or Item objects. # Must return an iterable of Request, or item objects.
for i in result: for i in result:
yield i yield i
...@@ -39,8 +40,7 @@ class ElfinancieroSpiderMiddleware(object): ...@@ -39,8 +40,7 @@ class ElfinancieroSpiderMiddleware(object):
# Called when a spider or process_spider_input() method # Called when a spider or process_spider_input() method
# (from other spider middleware) raises an exception. # (from other spider middleware) raises an exception.
# Should return either None or an iterable of Response, dict # Should return either None or an iterable of Request or item objects.
# or Item objects.
pass pass
def process_start_requests(self, start_requests, spider): def process_start_requests(self, start_requests, spider):
...@@ -56,7 +56,7 @@ class ElfinancieroSpiderMiddleware(object): ...@@ -56,7 +56,7 @@ class ElfinancieroSpiderMiddleware(object):
spider.logger.info('Spider opened: %s' % spider.name) spider.logger.info('Spider opened: %s' % spider.name)
class ElfinancieroDownloaderMiddleware(object): class ElfinancieroDownloaderMiddleware:
# Not all methods need to be defined. If a method is not defined, # Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the downloader middleware does not modify the # scrapy acts as if the downloader middleware does not modify the
# passed objects. # passed objects.
......
# -*- coding: utf-8 -*-
# Define your item pipelines here # Define your item pipelines here
# #
# Don't forget to add your pipeline to the ITEM_PIPELINES setting # Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
import json
class ElfinancieroPipeline(object):
def __init__(self, filename):
self.filename = filename
@classmethod
def from_crawler(cls, crawler):
# Here you get whatever value was passed through the "filename" command line parameter
settings = crawler.settings
filename = settings.get('filename')
# Instantiate the pipeline with the file name
return cls(filename)
def open_spider(self, spider): # useful for handling different item types with a single interface
self.itemList=[] from itemadapter import ItemAdapter
def close_spider(self, spider):
# print(len(self.itemList))
with open(self.filename, 'w') as fp:
json.dump(self.itemList, fp)
class ElfinancieroPipeline:
def process_item(self, item, spider): def process_item(self, item, spider):
self.itemList.append(dict(item))
return item return item
# -*- coding: utf-8 -*-
# Scrapy settings for elFinanciero project # Scrapy settings for elFinanciero project
# #
# For simplicity, this file contains only settings considered important or # For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation: # commonly used. You can find more settings consulting the documentation:
# #
# https://doc.scrapy.org/en/latest/topics/settings.html # https://docs.scrapy.org/en/latest/topics/settings.html
# https://doc.scrapy.org/en/latest/topics/downloader-middleware.html # https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
# https://doc.scrapy.org/en/latest/topics/spider-middleware.html # https://docs.scrapy.org/en/latest/topics/spider-middleware.html
BOT_NAME = 'elFinanciero' BOT_NAME = 'elFinanciero'
SPIDER_MODULES = ['elFinanciero.spiders'] SPIDER_MODULES = ['elFinanciero.spiders']
NEWSPIDER_MODULE = 'elFinanciero.spiders' NEWSPIDER_MODULE = 'elFinanciero.spiders'
FEED_EXPORT_ENCODING="utf-8"
# Crawl responsibly by identifying yourself (and your website) on the user-agent # Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'elFinanciero (+http://www.yourdomain.com)' #USER_AGENT = 'elFinanciero (+http://www.yourdomain.com)'
...@@ -25,7 +23,7 @@ ROBOTSTXT_OBEY = True ...@@ -25,7 +23,7 @@ ROBOTSTXT_OBEY = True
#CONCURRENT_REQUESTS = 32 #CONCURRENT_REQUESTS = 32
# Configure a delay for requests for the same website (default: 0) # Configure a delay for requests for the same website (default: 0)
# See https://doc.scrapy.org/en/latest/topics/settings.html#download-delay # See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs # See also autothrottle settings and docs
#DOWNLOAD_DELAY = 3 #DOWNLOAD_DELAY = 3
# The download delay setting will honor only one of: # The download delay setting will honor only one of:
...@@ -45,31 +43,31 @@ ROBOTSTXT_OBEY = True ...@@ -45,31 +43,31 @@ ROBOTSTXT_OBEY = True
#} #}
# Enable or disable spider middlewares # Enable or disable spider middlewares
# See https://doc.scrapy.org/en/latest/topics/spider-middleware.html # See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = { #SPIDER_MIDDLEWARES = {
# 'elFinanciero.middlewares.ElfinancieroSpiderMiddleware': 543, # 'elFinanciero.middlewares.ElfinancieroSpiderMiddleware': 543,
#} #}
# Enable or disable downloader middlewares # Enable or disable downloader middlewares
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html # See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = { #DOWNLOADER_MIDDLEWARES = {
# 'elFinanciero.middlewares.ElfinancieroDownloaderMiddleware': 543, # 'elFinanciero.middlewares.ElfinancieroDownloaderMiddleware': 543,
#} #}
# Enable or disable extensions # Enable or disable extensions
# See https://doc.scrapy.org/en/latest/topics/extensions.html # See https://docs.scrapy.org/en/latest/topics/extensions.html
#EXTENSIONS = { #EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None, # 'scrapy.extensions.telnet.TelnetConsole': None,
#} #}
# Configure item pipelines # Configure item pipelines
# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html # See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = { #ITEM_PIPELINES = {
'elFinanciero.pipelines.ElfinancieroPipeline': 300, # 'elFinanciero.pipelines.ElfinancieroPipeline': 300,
} #}
# Enable and configure the AutoThrottle extension (disabled by default) # Enable and configure the AutoThrottle extension (disabled by default)
# See https://doc.scrapy.org/en/latest/topics/autothrottle.html # See https://docs.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True #AUTOTHROTTLE_ENABLED = True
# The initial download delay # The initial download delay
#AUTOTHROTTLE_START_DELAY = 5 #AUTOTHROTTLE_START_DELAY = 5
...@@ -82,7 +80,7 @@ ITEM_PIPELINES = { ...@@ -82,7 +80,7 @@ ITEM_PIPELINES = {
#AUTOTHROTTLE_DEBUG = False #AUTOTHROTTLE_DEBUG = False
# Enable and configure HTTP caching (disabled by default) # Enable and configure HTTP caching (disabled by default)
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings # See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True #HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0 #HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache' #HTTPCACHE_DIR = 'httpcache'
......
# -*- coding: utf-8 -*-
""" """
MEDIA: Spider for elfinanciero.com.mx
El Financiero Author: Mario Chirinos Coluga
USAGE: Usage:scrapy crawl noticias --nolog -O 2021-03-18.json -a year=2021 -a month=3 -a day=18
## Get all the news from a specific date. ##
---------------------------------------------------------------------------------------------
$ cd elFinanciero/
$ scrapy crawl noticias --nolog -s filename=2017-03-22.json -a year=2017 -a month=3 -a day=22
""" """
import scrapy
import json
import re
from elFinanciero.items import ElfinancieroItem
import scrapy, re, json #-------------------------------------------------------------------------------
from elFinanciero.items import NoticiasItem
from datetime import datetime, timedelta, tzinfo
#------------------------------------------------------------------------------------------------
allSections = [{"name":"Economía","slug":"economia"},{"name":"Empresas","slug":"empresas"},{"name":"Mercados","slug":"mercados"},{"name":"Pyme","slug":"pyme"},{"name":"Franquicias","slug":"franquicias"},{"name":"Nacional","slug":"nacional"},{"name":"Tech","slug":"tech"},{"name":"Mundo","slug":"mundo"},{"name":"Deportes","slug":"deportes"},{"name":"Culturas","slug":"culturas"},{"name":"Buena Vida","slug":"buena-vida"},{"name":"Reflector","slug":"reflector"},{"name":"Ciencia","slug":"ciencia"},{"name":"Mis Finanzas","slug":"mis-finanzas"},{"name":"Opinión","slug":"opinion"},{"name":"Interactivos","slug":"interactivos"},{"name":"Blogs","slug":"blogs"},{"name":"Fotogalerías","slug":"fotogalerias"},{"name":"Financial Times","slug":"financial-times"},{"name":"Power Tools","slug":"power-tools"},{"name":"Bajío","slug":"bajio"},{"name":"Monterrey","slug":"monterrey"},{"name":"Universidades","slug":"universidades"},{"name":"Mundo empresa","slug":"mundo-empresa"},{"name":"Texas","slug":"texas"},{"name":"Suplementos","slug":"suplementos"},{"name":"Archivo","slug":"archivo"},{"name":"Pages","slug":"pages"},{"name":"Licitaciones","slug":"licitaciones"},{"name":"Bloomberg","slug":"bloomberg"},{"name":"Startup","slug":"startup"},{"name":"Mercados - Acciones","slug":"mercados/acciones"},{"name":"Mercados - IPC","slug":"mercados/ipc"},{"name":"Mercados - Divisas","slug":"mercados/divisas"},{"name":"Mercados - Dinero","slug":"mercados/dinero"},{"name":"Mercados - Commodities","slug":"mercados/commodities"},{"name":"TLCAN","slug":"tlcan"},{"name":"Blogs - Territorio Viral","slug":"blogs/territorio-viral"},{"name":"Blogs - Templo del Morbo","slug":"blogs/templo-del-morbo"},{"name":"Sponsor","slug":"sponsor"},{"name":"Bloomberg Businessweek","slug":"bloomberg-businessweek"},{"name":"Millonarios","slug":"millonarios"},{"name":"Management","slug":"management"},{"name":"Viajes","slug":"viajes"},{"name":"Cartones","slug":"cartones"},{"name":"EF Eventos","slug":"ef-eventos"},{"name":"Blogs - Efecto Jazz","slug":"blogs/efecto-jazz"},{"name":"Blogs - Visión CFA","slug":"blogs/vision-cfa"},{"name":"Pages - Eventos","slug":"pages/eventos"},{"name":"Pages - Interactivos","slug":"pages/interactivos"},{"name":"Pages - PDF","slug":"pages/pdf"},{"name":"Pages - Documentos","slug":"pages/documentos"},{"name":"Pages - Docs","slug":"pages/docs"},{"name":"TV","slug":"tv"},{"name":"Tv - Al sonar la campana","slug":"tv/al-sonar-la-campana"},{"name":"Tv - Espresso Doble","slug":"tv/espresso-doble"},{"name":"Tv - Ganadores & Perdedores","slug":"tv/ganadores-y-perdedores"},{"name":"Tv - Entre Mercados","slug":"tv/entre-mercados"},{"name":"Tv - Mesa Central","slug":"tv/mesa-central"},{"name":"Tv - Bitácora Política","slug":"tv/bitacora-politica"},{"name":"Tv - Sin Línea","slug":"tv/sin-linea"},{"name":"Tv - Al Cierre","slug":"tv/al-cierre"},{"name":"Tv - Tiempo de Toros","slug":"tv/tiempo-de-toros"},{"name":"Tv - Nación 321","slug":"tv/nacion321"},{"name":"Tv - El mundo según...","slug":"tv/el-mundo-segun"},{"name":"Tv - En EF y por Adela","slug":"tv/en-ef-y-por-adela"},{"name":"Tv - La Nota Dura","slug":"tv/la-nota-dura"},{"name":"Tv - La Silla Roja","slug":"tv/la-silla-roja"},{"name":"Tv - Personajes","slug":"tv/personajes"},{"name":"Tv - Tech","slug":"tv/tech"},{"name":"Tv - Mundo","slug":"tv/mundo"},{"name":"Tv - Finanzas Personales","slug":"tv/finanzas-personales"},{"name":"Tv - Estilo de Vida","slug":"tv/estilo-de-vida"},{"name":"Tv - Bloomberg","slug":"tv/bloomberg"},{"name":"Tv - Viral","slug":"tv/viral"},{"name":"Tv - Nacional","slug":"tv/nacional"},{"name":"Tv - Empresas","slug":"tv/empresas"},{"name":"Tv - Economía","slug":"tv/economia"},{"name":"Tv - Reflector","slug":"tv/reflector"},{"name":"Tv - Sponsor","slug":"tv/sponsor"},{"name":"Rankings","slug":"rankings"},{"name":"Trivias","slug":"trivias"},{"name":"Elecciones 2018","slug":"elecciones-2018"},{"name":"Pages - Businessweek México","slug":"pages/businessweek-mexico"},{"name":"Fibras","slug":"fibras"},{"name":"After Office","slug":"after-office"},{"name":"New York Times Syndicate","slug":"new-york-times-syndicate"},{"name":"México en Hannover","slug":"mexico-en-hannover"},{"name":"Tv - Opinión","slug":"tv/opinion"},{"name":"Pages - Central Política","slug":"pages/central-politica"},{"name":"Relojes","slug":"relojes"},{"name":"Autos","slug":"autos"},{"name":"Sibarita","slug":"sibarita"},{"name":"Letras Libres","slug":"letras-libres"},{"name":"Rusia 2018","slug":"rusia-2018"},{"name":"Tv - Especiales","slug":"tv/especiales"},{"name":"Tv - Bloomberg Businessweek","slug":"tv/bloomberg-businessweek"},{"name":"Tv - Gabinete de Seguridad","slug":"tv/gabinete-de-seguridad"},{"name":"Transición","slug":"transicion"},{"name":"Emprendedores","slug":"emprendedores"},{"name":"Blogs - Monoblock","slug":"blogs/monoblock"},{"name":"Península","slug":"peninsula"},{"name":"ESPN","slug":"espn"},{"name":"Tv - La Cuarta Transformación","slug":"tv/la-cuarta-transformacion"},{"name":"Primeros 100 días","slug":"primeros-100-dias"}]
#------------------------------------------------------------------------------------------------
TAG_RE = re.compile(r'<[^>]+>') TAG_RE = re.compile(r'<[^>]+>')
def remove_tags(text): def remove_tags(text):
return TAG_RE.sub('', text) return TAG_RE.sub('', text)
#-------------------------------------------------------------------------------
class NoticiasSpider(scrapy.Spider):
name = 'noticias'
allowed_domains = ['elfinanciero.com']
start_urls = ['http://elfinanciero.com/']
urllist=[]
def start_requests(self):
print("start_urls")
yield scrapy.Request(url=self.start_urls[0]+"search/", callback=self.parseSections)
#------------------------------------------------------------------------------------------------ def parseSections(self, response):
class QuotesSpider(scrapy.Spider): print(response.url)
""" sections = json.loads(re.findall("var allSections = (.+?);\n", response.body.decode("utf-8"), re.S)[0])
Basic Scrapy Spider class
"""
name = "noticias"
def start_requests(self): for i in sections:
year = getattr(self, "year", None) year = getattr(self, "year", None)
month = getattr(self, "month", None) month = getattr(self, "month", None)
self.day = getattr(self, "day", None) day = getattr(self, "day", None)
self.date = year + "-" + month.zfill(2) + "-" + day.zfill(2)
self.this_date = year + "-" + month.zfill(2) + "-" + self.day.zfill(2) url = 'https://api.elfinanciero.com/public/search/typed/?_format:json&json={"categoriesslug":"'+i["slug"]+'","min_date":"'+self.date+'","max_date":"'+self.date+'"}'
self.baseURL1 = "https://api.elfinanciero.com.mx/public/search/typed/?_format=json&json={%22search%22:%22*%22,%22categoriesslug%22:%22" yield scrapy.Request(url=url, callback=self.parse)
self.baseURL2 = "%22,%22min_date%22:%22"+self.this_date+"%22,%22max_date%22:%22"+self.this_date+"%22}&type=page&page=1&size=10000"
# print(self.baseURL)
for i in allSections:
yield scrapy.Request(url=self.baseURL1+i["slug"]+self.baseURL2, callback=self.parse)
def parse(self, response): def parse(self, response):
data = json.loads(response.text)["data"][1] data = json.loads(response.text)["data"][1]
for d in data: for d in data:
item = NoticiasItem() item = ElfinancieroItem()
item["title"] = d["_source"]["title"]
item["date"] = d["_source"]["createdAt"] item["date"] = d["_source"]["createdAt"]
item["title"] = d["_source"]["title"]
item["text"]=remove_tags(d["_source"]["html"]) item["text"]=remove_tags(d["_source"]["html"])
item["topic"]=d["_source"]["categoryId"]["slug"] item["topic"]=d["_source"]["categoryId"]["slug"]
item["author"]=d["_source"]["author"][0]["name"]+" "+d["_source"]["author"][0]["aPaterno"]+" "+d["_source"]["author"][0]["aMaterno"] item["author"]=d["_source"]["author"][0]["name"]+" "+d["_source"]["author"][0]["aPaterno"]+" "+d["_source"]["author"][0]["aMaterno"]
item["url"]="https://elfinanciero.com.mx/"+d["_source"]["slug"] item["url"]="https://elfinanciero.com/"+d["_source"]["slug"]
item["media"]="https://elfinanciero.com/"+d["_source"]["mainImage"]
if item["url"] not in self.urllist and len(item["text"])>0:
self.urllist.append(item['url'])
print(item["title"])
yield item yield item
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class NoticiasItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
text = scrapy.Field()
date = scrapy.Field()
location = scrapy.Field()
author = scrapy.Field()
topic = scrapy.Field()
url = scrapy.Field()
twitter = scrapy.Field()
email = scrapy.Field()
# -*- coding: utf-8 -*-
# Define here the models for your spider middleware
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/spider-middleware.html
from scrapy import signals
class DiariocolatinoSpiderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the spider middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_spider_input(self, response, spider):
# Called for each response that goes through the spider
# middleware and into the spider.
# Should return None or raise an exception.
return None
def process_spider_output(self, response, result, spider):
# Called with the results returned from the Spider, after
# it has processed the response.
# Must return an iterable of Request, dict or Item objects.
for i in result:
yield i
def process_spider_exception(self, response, exception, spider):
# Called when a spider or process_spider_input() method
# (from other spider middleware) raises an exception.
# Should return either None or an iterable of Response, dict
# or Item objects.
pass
def process_start_requests(self, start_requests, spider):
# Called with the start requests of the spider, and works
# similarly to the process_spider_output() method, except
# that it doesn’t have a response associated.
# Must return only requests (not items).
for r in start_requests:
yield r
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
class DiariocolatinoDownloaderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the downloader middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_request(self, request, spider):
# Called for each request that goes through the downloader
# middleware.
# Must either:
# - return None: continue processing this request
# - or return a Response object
# - or return a Request object
# - or raise IgnoreRequest: process_exception() methods of
# installed downloader middleware will be called
return None
def process_response(self, request, response, spider):
# Called with the response returned from the downloader.
# Must either;
# - return a Response object
# - return a Request object
# - or raise IgnoreRequest
return response
def process_exception(self, request, exception, spider):
# Called when a download handler or a process_request()
# (from other downloader middleware) raises an exception.
# Must either:
# - return None: continue processing this exception
# - return a Response object: stops process_exception() chain
# - return a Request object: stops process_exception() chain
pass
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
import json
from collections import OrderedDict
class JsonWriterPipeline(object):
def __init__(self, filename):
self.filename = filename
@classmethod
def from_crawler(cls, crawler):
# Here you get whatever value was passed through the "filename" command line parameter
settings = crawler.settings
filename = settings.get('filename')
# Instantiate the pipeline with the file name
return cls(filename)
def open_spider(self, spider):
self.counter = 0
self.file = open(self.filename, 'w')
self.file.write("[")
def close_spider(self, spider):
self.file.write("]")
self.file.close()
def process_item(self, item, spider):
# print("this is my item", item)
row = []
try:
row.append(("date", item['date']))
except:
pass
try:
row.append(("topic", item['topic']))
except:
pass
try:
row.append(("title", item['title']))
except:
pass
try:
row.append(("author", item['author']))
except:
pass
try:
row.append(("location", item['location']))
except:
pass
try:
row.append(("twitter", item['twitter']))
except:
pass
try:
row.append(("email", item['email']))
except:
pass
try:
row.append(("text", item['text']))
except:
pass
try:
row.append(("url", item['url']))
except:
pass
line = OrderedDict(row)
self.counter += 1
if self.counter == 1:
self.file.write(json.dumps(line))
elif self.counter > 1:
self.file.write(",\n" + json.dumps(line))
return item
# -*- coding: utf-8 -*-
# Scrapy settings for diarioCoLatino project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
# https://doc.scrapy.org/en/latest/topics/settings.html
# https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
# https://doc.scrapy.org/en/latest/topics/spider-middleware.html
BOT_NAME = 'diarioCoLatino'
SPIDER_MODULES = ['diarioCoLatino.spiders']
NEWSPIDER_MODULE = 'diarioCoLatino.spiders'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'diarioCoLatino (+http://www.yourdomain.com)'
# Obey robots.txt rules
# ROBOTSTXT_OBEY = True
# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32
# Configure a delay for requests for the same website (default: 0)
# See https://doc.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.5
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16
# Disable cookies (enabled by default)
COOKIES_ENABLED = False
# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False
# Override the default request headers:
#DEFAULT_REQUEST_HEADERS = {
# 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
# 'Accept-Language': 'en',
#}
# Enable or disable spider middlewares
# See https://doc.scrapy.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
# 'diarioCoLatino.middlewares.DiariocolatinoSpiderMiddleware': 543,
#}
# Enable or disable downloader middlewares
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
# 'diarioCoLatino.middlewares.DiariocolatinoDownloaderMiddleware': 543,
#}
# Enable or disable extensions
# See https://doc.scrapy.org/en/latest/topics/extensions.html
#EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None,
#}
# Configure item pipelines
# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'diarioCoLatino.pipelines.JsonWriterPipeline': 300,
}
# Enable and configure the AutoThrottle extension (disabled by default)
# See https://doc.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True
# The initial download delay
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False
# Enable and configure HTTP caching (disabled by default)
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
# This package will contain the spiders of your Scrapy project
#
# Please refer to the documentation for information on how to create and manage
# your spiders.
# -*- coding: utf-8 -*-
"""
MEDIA:
Diario Co Latino, El Salvador
USAGE:
## Get all the news from a specific date. ##
---------------------------------------------------------------------------------------------
$ cd diarioCoLatino/
$ scrapy crawl noticias --nolog -s filename=2018-02-23.json -a year=2018 -a month=2 -a day=23
"""
import scrapy, re
from diarioCoLatino.items import NoticiasItem
TAG_RE = re.compile(r'<[^>]+>')
def remove_tags(text):
return TAG_RE.sub('', text)
AUTH_RE = re.compile(r'\nPor.+?\n')
TW_RE = re.compile(r'\n((\| )?Twitter:\s+)?@[\w.%+-]+.\n', re.I)
LOC_RE = re.compile(r'\n.*?\/(PL|AFP|DPA|SIGNIS ALC)\n', re.I)
EM_RE = re.compile(r'\n((Email|Correo electr.{1,3}nico|Comentarios?):\s)?[\w.-]+@[\w-]+(\.[a-zA-Z]{2,6}){1,2}\s?\n')
class QuotesSpider(scrapy.Spider):
"""
Basic Scrapy Spider class
"""
name = "noticias"
def start_requests(self):
year = getattr(self, "year", None)
month = getattr(self, "month", None)
day = getattr(self, "day", None)
self.baseURL = "https://www.diariocolatino.com/" + year + "/" + month.zfill(2) + "/" + day.zfill(2)
yield scrapy.Request(url=self.baseURL, callback=self.parse)
def parse(self, response):
yield scrapy.Request(url=response.url, callback=self.parse_page, dont_filter=True)
pagination = response.xpath('//div[@class="pagination"]/a/@href').extract()
if len(pagination) > 0:
pagination = pagination[-1].strip('/')
pages = int(pagination[pagination.rfind('/') + 1:])
for page in range(1, pages):
yield scrapy.Request(url=self.baseURL + "/page/" + str(page + 1), callback=self.parse_page)
def parse_page(self, response):
for link in response.css('div.content').css('div.post-listing').xpath('./article/h2/a/@href').extract():
yield scrapy.Request(url=link, callback=self.parse_item)
def parse_item(self, response):
item = NoticiasItem()
text = ''
# La fecha obtenida ya incluye formato y zona horaria
news_date = response.xpath('//meta[@property="article:published_time"]/@content').extract_first()
news_title = remove_tags(response.css('h1.entry-title').css('span').extract_first()).strip()
news_topic = None
for p in response.xpath('//div[@class="entry"]/p').extract():
text += remove_tags(p) + "\n"
if text == '':
for p in response.xpath('//div[@class="entry"]/div/span').extract():
text += remove_tags(p) + "\n"
text = "\n" + text
""" Obtiene autor """
news_author = None
res = AUTH_RE.match(text)
if res:
m = res.group(0)
news_author = m[m.find('Por')+len('Por'):].strip()
text = text[text.find(m) + len(m):].strip()
text = "\n" + text
""" Elimina twitter """
news_twitter = None
res = TW_RE.search(text)
if res:
m = res.group(0)
news_twitter = m.strip()
text = text[text.find(m) + len(m):].strip()
text = "\n" + text
""" Obtiene lugar """
news_loc = None
res = LOC_RE.match(text)
if res:
m = res.group(0)
if m[m.find('/') + 1:].strip().lower() != 'dpa':
news_loc = m[:m.find('/')].strip()
text = text[text.find(m) + len(m):].strip()
text = "\n" + text
else:
text = text[text.find(m) + len(m):].strip()
text = "\n" + text
""" Elimina correo """
news_email = None
res = EM_RE.search(text)
if res:
m = res.group(0)
news_email = m.strip()
# text = text[text.find(m) + len(m):].strip()
text = text.replace(m, '').strip()
text = "\n" + text
res = EM_RE.search(text)
if res:
m = res.group(0)
news_email = m.strip()
# text = text[text.find(m) + len(m):].strip()
text = text.replace(m, '').strip()
text = "\n" + text
text = text.replace("\n@Diario Co Latino\n", '').strip()
text = "\n" + text
text = text.replace("\nDiario Co Latino\n", '').strip()
text = "\n" + text
text = text.replace("\nCo Latino\n", '').strip()
## News item info ##
item['date'] = news_date
item['title'] = news_title
item['topic'] = news_topic
item['author'] = news_author
item['twitter'] = news_twitter
item['location'] = news_loc
item['email'] = news_email
item['text'] = text.strip()
item['url'] = response.url
yield item
# Automatically created by: scrapy startproject
#
# For more information about the [deploy] section see:
# https://scrapyd.readthedocs.io/en/latest/deploy.html
[settings]
default = diarioCoLatino.settings
[deploy]
#url = http://localhost:6800/
project = diarioCoLatino
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class NoticiasItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
text = scrapy.Field()
date = scrapy.Field()
location = scrapy.Field()
author = scrapy.Field()
topic = scrapy.Field()
url = scrapy.Field()
# -*- coding: utf-8 -*-
# Define here the models for your spider middleware
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/spider-middleware.html
from scrapy import signals
class SanpedrosunSpiderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the spider middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_spider_input(self, response, spider):
# Called for each response that goes through the spider
# middleware and into the spider.
# Should return None or raise an exception.
return None
def process_spider_output(self, response, result, spider):
# Called with the results returned from the Spider, after
# it has processed the response.
# Must return an iterable of Request, dict or Item objects.
for i in result:
yield i
def process_spider_exception(self, response, exception, spider):
# Called when a spider or process_spider_input() method
# (from other spider middleware) raises an exception.
# Should return either None or an iterable of Response, dict
# or Item objects.
pass
def process_start_requests(self, start_requests, spider):
# Called with the start requests of the spider, and works
# similarly to the process_spider_output() method, except
# that it doesn’t have a response associated.
# Must return only requests (not items).
for r in start_requests:
yield r
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
class SanpedrosunDownloaderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the downloader middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_request(self, request, spider):
# Called for each request that goes through the downloader
# middleware.
# Must either:
# - return None: continue processing this request
# - or return a Response object
# - or return a Request object
# - or raise IgnoreRequest: process_exception() methods of
# installed downloader middleware will be called
return None
def process_response(self, request, response, spider):
# Called with the response returned from the downloader.
# Must either;
# - return a Response object
# - return a Request object
# - or raise IgnoreRequest
return response
def process_exception(self, request, exception, spider):
# Called when a download handler or a process_request()
# (from other downloader middleware) raises an exception.
# Must either:
# - return None: continue processing this exception
# - return a Response object: stops process_exception() chain
# - return a Request object: stops process_exception() chain
pass
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
import json
from collections import OrderedDict
class JsonWriterPipeline(object):
def __init__(self, filename):
self.filename = filename
@classmethod
def from_crawler(cls, crawler):
# Here you get whatever value was passed through the "filename" command line parameter
settings = crawler.settings
filename = settings.get('filename')
# Instantiate the pipeline with the file name
return cls(filename)
def open_spider(self, spider):
self.counter = 0
self.file = open(self.filename, 'w')
self.file.write("[")
def close_spider(self, spider):
self.file.write("]")
self.file.close()
def process_item(self, item, spider):
# print("this is my item", item)
row = []
try:
row.append(("date", item['date']))
except:
pass
try:
row.append(("topic", item['topic']))
except:
pass
try:
row.append(("title", item['title']))
except:
pass
try:
row.append(("author", item['author']))
except:
pass
try:
row.append(("location", item['location']))
except:
pass
try:
row.append(("text", item['text']))
except:
pass
try:
row.append(("url", item['url']))
except:
pass
line = OrderedDict(row)
self.counter += 1
if self.counter == 1:
self.file.write(json.dumps(line))
elif self.counter > 1:
self.file.write(",\n" + json.dumps(line))
return item
# -*- coding: utf-8 -*-
# Scrapy settings for sanPedroSun project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
# https://doc.scrapy.org/en/latest/topics/settings.html
# https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
# https://doc.scrapy.org/en/latest/topics/spider-middleware.html
BOT_NAME = 'sanPedroSun'
SPIDER_MODULES = ['sanPedroSun.spiders']
NEWSPIDER_MODULE = 'sanPedroSun.spiders'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'sanPedroSun (+http://www.yourdomain.com)'
# Obey robots.txt rules
# ROBOTSTXT_OBEY = True
# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32
# Configure a delay for requests for the same website (default: 0)
# See https://doc.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.5
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16
# Disable cookies (enabled by default)
COOKIES_ENABLED = False
# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False
# Override the default request headers:
#DEFAULT_REQUEST_HEADERS = {
# 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
# 'Accept-Language': 'en',
#}
# Enable or disable spider middlewares
# See https://doc.scrapy.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
# 'sanPedroSun.middlewares.SanpedrosunSpiderMiddleware': 543,
#}
# Enable or disable downloader middlewares
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
# 'sanPedroSun.middlewares.SanpedrosunDownloaderMiddleware': 543,
#}
# Enable or disable extensions
# See https://doc.scrapy.org/en/latest/topics/extensions.html
#EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None,
#}
# Configure item pipelines
# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'sanPedroSun.pipelines.JsonWriterPipeline': 300,
}
# Enable and configure the AutoThrottle extension (disabled by default)
# See https://doc.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True
# The initial download delay
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False
# Enable and configure HTTP caching (disabled by default)
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
# This package will contain the spiders of your Scrapy project
#
# Please refer to the documentation for information on how to create and manage
# your spiders.
# -*- coding: utf-8 -*-
import scrapy, re
from sanPedroSun.items import NoticiasItem
"""
MEDIO:
The San Pedro Sun, Belice
USO:
scrapy crawl noticias --nolog -s filename=2018-02-23.json -a year=2018 -a month=2 -a day=23
"""
TAG_RE = re.compile(r'<[^>]+>')
def remove_tags(text):
return TAG_RE.sub('', text)
DATE_RE1 = re.compile(r'(-|- )?([A-Z][a-z]+, ?)?[A-Z][a-z]+( \d{1,2})?, \d{4}( -|\n)? ?[A-Z]')
DATE_RE2 = re.compile(r', [a-zA-Z]+ \d{1,2} -( -)?')
AUTH_RE = re.compile(r'\n(- )?By.+\n')
class importantData(scrapy.Item):
page = scrapy.Field()
class QuotesSpider(scrapy.Spider):
name = "noticias"
globalSet = set()
def start_requests(self):
year = getattr(self, "year", None)
month = getattr(self, "month", None)
day = getattr(self, "day", None)
self.baseURL = "https://www.sanpedrosun.com/wp-content/themes/sunbase/GetResults.php?year=" + year + "&monthnum=" + month + "&day=" + day + "&posts_per_page=8&n_view=standard&n_style=list"
# self.baseURL = "https://www.sanpedrosun.com/wp-content/themes/sunbase/GetResults.php?year=" + year + "&monthnum=" + month + "&posts_per_page=8&n_view=standard&n_style=list"
searchData = importantData()
searchData['page'] = 0
request = scrapy.Request(url=self.baseURL, callback=self.parse)
request.meta['item'] = searchData
yield request
def parse(self, response):
localSet = set(response.css('div.entry').xpath('./h2/a/@href').extract())
resultSet = localSet - self.globalSet
if len(resultSet) > 0:
searchData = response.meta['item']
for link in resultSet:
self.globalSet.add(link)
yield scrapy.Request(url=link, callback=self.parse_item)
searchData['page'] += 1
page = searchData['page']
request = scrapy.Request(url=response.url + "&n_more=" + str(page), callback=self.parse)
request.meta['item'] = searchData
yield request
def parse_page(self, response):
for link in response.css('div.td-ss-main-content').css('div.item-details').xpath('./h3/a/@href').extract():
yield scrapy.Request(url=link, callback=self.parse_item)
def parse_item(self, response):
item = NoticiasItem()
text = ''
"La fecha obtenida ya incluye formato y zona horaria"
item['date'] = response.xpath('//meta[@property="article:published_time"]/@content').extract_first()
item['title'] = remove_tags(response.xpath('//div[@class="post"]/h1').extract_first()).strip()
try:
topic = response.xpath('//div[@class="breadcrumb"]/p/a/text()').extract()[-1]
except:
try:
topic = response.xpath('//ul[@class="td-category"]/li/a/text()').extract_first()
except:
topic = None
item['topic'] = topic
for p in response.xpath('//div[@class="entry"]').css('p').extract():
text += remove_tags(p) + "\n"
text = text.strip()
text = "\n" + text
text = text.replace(u'\u2013', "-")
text = text.replace(u'\u00a0', '') ## Elimina 'no-break spaces'
res = DATE_RE1.search(text)
if res:
m = res.group(0)[:-1]
text = text[text.find(m) + len(m):].strip()
text = "\n" + text
res = DATE_RE2.search(text)
if res:
m = res.group(0)[:-1]
text = text[text.find(m) + len(m):].strip()
text = "\n" + text
res = AUTH_RE.match(text)
if res:
m = res.group(0)
text = text[text.find(m) + len(m):].strip()
text = "\n" + text
text = text.replace("Follow The San Pedro Sun News on Twitter, become a fan on Facebook. Stay updated via RSS", '')
item['text'] = text.strip()
item['url'] = response.url
yield item
# Automatically created by: scrapy startproject
#
# For more information about the [deploy] section see:
# https://scrapyd.readthedocs.io/en/latest/deploy.html
[settings]
default = sanPedroSun.settings
[deploy]
#url = http://localhost:6800/
project = sanPedroSun
# Automatically created by: scrapy startproject
#
# For more information about the [deploy] section see:
# https://scrapyd.readthedocs.io/en/latest/deploy.html
[settings]
default = tiempoDigitalHn.settings
[deploy]
#url = http://localhost:6800/
project = tiempoDigitalHn
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class NoticiasItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
text = scrapy.Field()
date = scrapy.Field()
location = scrapy.Field()
author = scrapy.Field()
topic = scrapy.Field()
url = scrapy.Field()
# -*- coding: utf-8 -*-
# Define here the models for your spider middleware
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/spider-middleware.html
from scrapy import signals
class TiempodigitalhnSpiderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the spider middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_spider_input(self, response, spider):
# Called for each response that goes through the spider
# middleware and into the spider.
# Should return None or raise an exception.
return None
def process_spider_output(self, response, result, spider):
# Called with the results returned from the Spider, after
# it has processed the response.
# Must return an iterable of Request, dict or Item objects.
for i in result:
yield i
def process_spider_exception(self, response, exception, spider):
# Called when a spider or process_spider_input() method
# (from other spider middleware) raises an exception.
# Should return either None or an iterable of Response, dict
# or Item objects.
pass
def process_start_requests(self, start_requests, spider):
# Called with the start requests of the spider, and works
# similarly to the process_spider_output() method, except
# that it doesn’t have a response associated.
# Must return only requests (not items).
for r in start_requests:
yield r
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
class TiempodigitalhnDownloaderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the downloader middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_request(self, request, spider):
# Called for each request that goes through the downloader
# middleware.
# Must either:
# - return None: continue processing this request
# - or return a Response object
# - or return a Request object
# - or raise IgnoreRequest: process_exception() methods of
# installed downloader middleware will be called
return None
def process_response(self, request, response, spider):
# Called with the response returned from the downloader.
# Must either;
# - return a Response object
# - return a Request object
# - or raise IgnoreRequest
return response
def process_exception(self, request, exception, spider):
# Called when a download handler or a process_request()
# (from other downloader middleware) raises an exception.
# Must either:
# - return None: continue processing this exception
# - return a Response object: stops process_exception() chain
# - return a Request object: stops process_exception() chain
pass
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
import json
from collections import OrderedDict
class JsonWriterPipeline(object):
def __init__(self, filename):
self.filename = filename
@classmethod
def from_crawler(cls, crawler):
# Here you get whatever value was passed through the "filename" command line parameter
settings = crawler.settings
filename = settings.get('filename')
# Instantiate the pipeline with the file name
return cls(filename)
def open_spider(self, spider):
self.counter = 0
self.file = open(self.filename, 'w')
self.file.write("[")
def close_spider(self, spider):
self.file.write("]")
self.file.close()
def process_item(self, item, spider):
# print("this is my item", item)
row = []
try:
row.append(("date", item['date']))
except:
pass
try:
row.append(("topic", item['topic']))
except:
pass
try:
row.append(("title", item['title']))
except:
pass
try:
row.append(("author", item['author']))
except:
pass
try:
row.append(("location", item['location']))
except:
pass
try:
row.append(("text", item['text']))
except:
pass
try:
row.append(("url", item['url']))
except:
pass
line = OrderedDict(row)
self.counter += 1
if self.counter == 1:
self.file.write(json.dumps(line))
elif self.counter > 1:
self.file.write(",\n" + json.dumps(line))
return item
# -*- coding: utf-8 -*-
# Scrapy settings for tiempoDigitalHn project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
# https://doc.scrapy.org/en/latest/topics/settings.html
# https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
# https://doc.scrapy.org/en/latest/topics/spider-middleware.html
BOT_NAME = 'tiempoDigitalHn'
SPIDER_MODULES = ['tiempoDigitalHn.spiders']
NEWSPIDER_MODULE = 'tiempoDigitalHn.spiders'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'tiempoDigitalHn (+http://www.yourdomain.com)'
# Obey robots.txt rules
# ROBOTSTXT_OBEY = True
# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32
# Configure a delay for requests for the same website (default: 0)
# See https://doc.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.5
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16
# Disable cookies (enabled by default)
COOKIES_ENABLED = False
# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False
# Override the default request headers:
#DEFAULT_REQUEST_HEADERS = {
# 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
# 'Accept-Language': 'en',
#}
# Enable or disable spider middlewares
# See https://doc.scrapy.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
# 'tiempoDigitalHn.middlewares.TiempodigitalhnSpiderMiddleware': 543,
#}
# Enable or disable downloader middlewares
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
# 'tiempoDigitalHn.middlewares.TiempodigitalhnDownloaderMiddleware': 543,
#}
# Enable or disable extensions
# See https://doc.scrapy.org/en/latest/topics/extensions.html
#EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None,
#}
# Configure item pipelines
# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'tiempoDigitalHn.pipelines.JsonWriterPipeline': 300,
}
# Enable and configure the AutoThrottle extension (disabled by default)
# See https://doc.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True
# The initial download delay
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False
# Enable and configure HTTP caching (disabled by default)
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
# This package will contain the spiders of your Scrapy project
#
# Please refer to the documentation for information on how to create and manage
# your spiders.
# -*- coding: utf-8 -*-
import scrapy, re
from tiempoDigitalHn.items import NoticiasItem
"""
MEDIO:
Tiempo Digital, Honduras
USO:
scrapy crawl noticias --nolog -s filename=2018-02-23.json -a year=2018 -a month=2 -a day=23
"""
TAG_RE = re.compile(r'<[^>]+>')
def remove_tags(text):
return TAG_RE.sub('', text)
LOC_RE1 = re.compile(r'\n([A-Z]+ )+ ?[.-]')
LOC_RE2 = re.compile(r'\n.+?,? ?.+? ?(\. ?-|\.|-) ?[A-Z]')
SOURCE_RE = re.compile(r'\n ?Fuente:.+$')
class QuotesSpider(scrapy.Spider):
name = "noticias"
def start_requests(self):
year = getattr(self, "year", None)
month = getattr(self, "month", None)
day = getattr(self, "day", None)
self.baseURL = "https://tiempo.hn/" + year + "/" + month.zfill(2) + "/" + day.zfill(2)
yield scrapy.Request(url=self.baseURL, callback=self.parse)
def parse(self, response):
yield scrapy.Request(url=response.url, callback=self.parse_page, dont_filter=True)
pagination = response.css('div.page-nav').xpath('./a/@href').extract()
if len(pagination) > 0:
try:
pagination = pagination[-2]
except:
pagination = pagination[-1]
pagination = pagination.strip('/')
pages = int(pagination[pagination.rfind('/') + 1:])
for page in range(1, pages):
yield scrapy.Request(url=self.baseURL + '/page/' + str(page + 1), callback=self.parse_page)
def parse_page(self, response):
for link in response.css('div.td-ss-main-content').css('div.td_module_1').xpath('./h3/a/@href').extract():
yield scrapy.Request(url=link, callback=self.parse_item)
def parse_item(self, response):
item = NoticiasItem()
text = ''
"La fecha obtenida ya incluye formato y zona horaria"
item['date'] = response.css('span.td-post-date').css('time.entry-date::attr(datetime)').extract_first()
item['title'] = remove_tags(response.xpath('//header[@class="td-post-title"]/h1').extract_first()).strip()
try:
topic = response.xpath('//ul[@class="td-category"]/li').extract()[-1]
item['topic'] = remove_tags(topic)
except:
item['topic'] = None
author = response.xpath('//div[@class="td-post-author-name"]/a').extract_first()
if author is not None:
item['author'] = remove_tags(author)
for p in response.xpath('//div[@class="td-post-content"]').css('p').extract():
text += remove_tags(p) + "\n"
text = text.strip()
text = "\n" + text
text = text.replace(u'\u2013', "-")
text = text.replace(u'\u00a0', '') ## Elimina 'no-break spaces'
res = LOC_RE1.match(text)
if res:
m = res.group(0)[:-1]
location = m.replace("-", '').strip()
if len(location) <= 25:
item['location'] = location
text = text.replace(m, '').strip()
text = "\n" + text
res = LOC_RE2.match(text)
if res:
m = res.group(0)[:-1]
location = m.replace("-", '').replace(".", '').strip()
if len(location) <= 25:
item['location'] = location
text = text.replace(m, '').strip()
text = "\n" + text
res = SOURCE_RE.search(text)
if res:
m = res.group(0)
text = text.replace(m, '').strip()
text = "\n" + text
item['text'] = text.strip()
item['url'] = response.url
yield item
# Automatically created by: scrapy startproject
#
# For more information about the [deploy] section see:
# https://scrapyd.readthedocs.io/en/latest/deploy.html
[settings]
default = tribunaHn.settings
[deploy]
#url = http://localhost:6800/
project = tribunaHn
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class NoticiasItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
text = scrapy.Field()
date = scrapy.Field()
location = scrapy.Field()
author = scrapy.Field()
topic = scrapy.Field()
url = scrapy.Field()
# -*- coding: utf-8 -*-
# Define here the models for your spider middleware
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/spider-middleware.html
from scrapy import signals
class TribunahnSpiderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the spider middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_spider_input(self, response, spider):
# Called for each response that goes through the spider
# middleware and into the spider.
# Should return None or raise an exception.
return None
def process_spider_output(self, response, result, spider):
# Called with the results returned from the Spider, after
# it has processed the response.
# Must return an iterable of Request, dict or Item objects.
for i in result:
yield i
def process_spider_exception(self, response, exception, spider):
# Called when a spider or process_spider_input() method
# (from other spider middleware) raises an exception.
# Should return either None or an iterable of Response, dict
# or Item objects.
pass
def process_start_requests(self, start_requests, spider):
# Called with the start requests of the spider, and works
# similarly to the process_spider_output() method, except
# that it doesn’t have a response associated.
# Must return only requests (not items).
for r in start_requests:
yield r
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
class TribunahnDownloaderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the downloader middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_request(self, request, spider):
# Called for each request that goes through the downloader
# middleware.
# Must either:
# - return None: continue processing this request
# - or return a Response object
# - or return a Request object
# - or raise IgnoreRequest: process_exception() methods of
# installed downloader middleware will be called
return None
def process_response(self, request, response, spider):
# Called with the response returned from the downloader.
# Must either;
# - return a Response object
# - return a Request object
# - or raise IgnoreRequest
return response
def process_exception(self, request, exception, spider):
# Called when a download handler or a process_request()
# (from other downloader middleware) raises an exception.
# Must either:
# - return None: continue processing this exception
# - return a Response object: stops process_exception() chain
# - return a Request object: stops process_exception() chain
pass
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
import json
from collections import OrderedDict
class JsonWriterPipeline(object):
def __init__(self, filename):
self.filename = filename
@classmethod
def from_crawler(cls, crawler):
# Here you get whatever value was passed through the "filename" command line parameter
settings = crawler.settings
filename = settings.get('filename')
# Instantiate the pipeline with the file name
return cls(filename)
def open_spider(self, spider):
self.counter = 0
self.file = open(self.filename, 'w')
self.file.write("[")
def close_spider(self, spider):
self.file.write("]")
self.file.close()
def process_item(self, item, spider):
# print("this is my item", item)
row = []
try:
row.append(("date", item['date']))
except:
pass
try:
row.append(("topic", item['topic']))
except:
pass
try:
row.append(("title", item['title']))
except:
pass
try:
row.append(("author", item['author']))
except:
pass
try:
row.append(("location", item['location']))
except:
pass
try:
row.append(("text", item['text']))
except:
pass
try:
row.append(("url", item['url']))
except:
pass
line = OrderedDict(row)
self.counter += 1
if self.counter == 1:
self.file.write(json.dumps(line))
elif self.counter > 1:
self.file.write(",\n" + json.dumps(line))
return item
# -*- coding: utf-8 -*-
# Scrapy settings for tribunaHn project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
# https://doc.scrapy.org/en/latest/topics/settings.html
# https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
# https://doc.scrapy.org/en/latest/topics/spider-middleware.html
BOT_NAME = 'tribunaHn'
SPIDER_MODULES = ['tribunaHn.spiders']
NEWSPIDER_MODULE = 'tribunaHn.spiders'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'tribunaHn (+http://www.yourdomain.com)'
# Obey robots.txt rules
# ROBOTSTXT_OBEY = True
# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32
# Configure a delay for requests for the same website (default: 0)
# See https://doc.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.5
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16
# Disable cookies (enabled by default)
COOKIES_ENABLED = False
# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False
# Override the default request headers:
#DEFAULT_REQUEST_HEADERS = {
# 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
# 'Accept-Language': 'en',
#}
# Enable or disable spider middlewares
# See https://doc.scrapy.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
# 'tribunaHn.middlewares.TribunahnSpiderMiddleware': 543,
#}
# Enable or disable downloader middlewares
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
# 'tribunaHn.middlewares.TribunahnDownloaderMiddleware': 543,
#}
# Enable or disable extensions
# See https://doc.scrapy.org/en/latest/topics/extensions.html
#EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None,
#}
# Configure item pipelines
# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'tribunaHn.pipelines.JsonWriterPipeline': 300,
}
# Enable and configure the AutoThrottle extension (disabled by default)
# See https://doc.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True
# The initial download delay
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False
# Enable and configure HTTP caching (disabled by default)
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
# This package will contain the spiders of your Scrapy project
#
# Please refer to the documentation for information on how to create and manage
# your spiders.
# -*- coding: utf-8 -*-
"""
MEDIA:
La Tribuna, Honduras
USAGE:
## Get all the news from a specific date. ##
---------------------------------------------------------------------------------------------
$ cd tribunaHn/
$ scrapy crawl noticias --nolog -s filename=noticias.json -a year=2018 -a month=2 -a day=29
"""
import scrapy, re
from tribunaHn.items import NoticiasItem
from datetime import datetime, timedelta, tzinfo
TAG_RE = re.compile(r'<[^>]+>')
def remove_tags(text):
return TAG_RE.sub('', text)
class UTC(tzinfo):
"""
Class for Time Zone
"""
def utcoffset(self, dt):
## Time zone for Honduras: UTC-6 ##
return timedelta(hours=-6)
def tzname(self, dt):
## Time zone name ##
return 'UTC-6'
class QuotesSpider(scrapy.Spider):
"""
Basic Scrapy Spider class
"""
name = "noticias"
def start_requests(self):
tz = UTC()
year = getattr(self, 'year', None)
month = getattr(self, 'month', None)
day = getattr(self, 'day', None)
self.news_date = datetime(int(year), int(month), int(day), tzinfo=tz).isoformat('T')
baseURL = 'http://www.latribuna.hn/' + year + '/' + month + '/' + day
yield scrapy.Request(url=baseURL, callback=self.parse)
def parse(self, response):
for link in response.xpath('//div[@id="main"]').css('h3 > a::attr(href)').extract():
yield scrapy.Request(url=link, callback=self.parse_item)
next_page = response.css('span.next > a::attr(href)').extract_first()
if next_page is not None:
yield scrapy.Request(url=next_page, callback=self.parse)
def parse_item(self, response):
text = ''
item = NoticiasItem()
title = response.css('article.article-post').css('h1').extract_first()
if title is not None: title = remove_tags(title)
topic = None
topic_list = response.css('aside.tags').css('li > a').extract()
if len(topic_list) > 0:
topic = remove_tags(topic_list[0])
for p in response.css('div.article-post-content').css('p').extract():
text += remove_tags(p) + '\n'
## News item info ##
item['date'] = self.news_date
item['title'] = title
item['topic'] = topic
item['text'] = text.strip()
item['url'] = response.url
yield item
[
{"date": "2019-04-23T16:16:18-05:00", "title": "Empresarios y autoridades consolidan Modelo Dual", "topic": "local", "text": "El Consejo Coordinador Empresarial y el Instituto de Educación de Aguascalientes analizaron el proyecto estratégico del Modelo de Formación Dual; se llevarán a cabo encuentros con empresas de manufactura, sector automotriz y de inversión extranjera, así como con pequeñas y medianas empresas locales que tengan interés de colaborar en esta estrategia.\n\nA través del Modelo de Formación Dual, se contempla al estudiante como un colaborador en el sector empresarial, por lo que recibe educación dentro de la empresa y realiza actividades propias de los procesos del corporativo. Además, se construirá un Consejo Consultivo de Educación Dual.\n\nPedro Gutiérrez Romo, dirigente del CCEA, y Gustavo Martínez Romero, director de Educación Media y Superior del IEA, señalaron que este esquema favorecerá la calidad en procesos de enseñanza en instituciones de nivel superior del estado.\n\nMartínez Romero destacó que se realizan actividades encaminadas a la vinculación entre el sector empresarial y universidades, a fin de avanzar en la construcción de un Consejo Consultivo de Educación Dual, el cual permitirá a las empresas e instituciones de educación superior desarrollar y atender procesos a favor de un Modelo de Formación Dual de alta competitividad.\n\nExplicó que este modelo precisa trabajo colaborativo entre la institución de educación superior y la empresa, con la finalidad de que los estudiantes reciban educación en ambas, de tal manera que se conjugue la educación teórica con la práctica, como parte del plan académico.\n\nMartínez Romero precisó que este modelo tiene el propósito de orientar el logro educativo a la productividad, competitividad, integración social, tecnologías e innovación, así como fomentar que los jóvenes construyan un proyecto de vida a largo plazo.\n\nPor último, se realizó un recorrido por “Espacio Común”, para mostrar a integrantes del Consejo Coordinador Empresarial las instalaciones, a las cuales acuden jóvenes de bachillerato con la finalidad de involucrarse en el uso de las Tecnologías de la Información y Comunicación, herramientas tecnológicas, de robótica, impresoras 3D, así como software de programación.\n", "url": "https://www.heraldo.mx/empresarios-y-autoridades-consolidan-modelo-dual/"},
{"date": "2019-04-23T16:38:03-05:00", "title": "Apoyo a víctimas de Tlahuelilpan durará todo el sexenio", "topic": "nacional", "text": "CIUDAD DE MÉXICO, (EL UNIVERSAL).- Las familias de las víctimas por la explosión en Tlahuelilpan, Hidalgo, recibirán apoyos económicos, de programas sociales y por violaciones a derechos humanos durante todo el sexenio.\n\nSin embargo, las familias de las víctimas buscan construir un memorial, ya que hay personas que no han sido ubicados.\n\nEn conferencia de prensa mañanera, la subsecretaria de Desarrollo Democrático y Participación Social, Diana Álvarez Maury, dijo que aún se encuentran hospitalizadas cinco personas y se dieron de alta nueve. El número de fallecidos fue de 135, de los cuales 68 fallecieron en el instante de la explosión y el resto en los hospitales.\n\nAl inicio se entregaron apoyos por 15 mil pesos a 157 familiares de fallecidos en el incidente.\n\nTambién se dieron recursos para la orfandad que se dará hasta que terminen su edad escolar, del programa beca a víctimas por violaciones a derechos humanos, así como apoyos psicológicos a familias.\n\nAsimismo, se dieron 148 mil pesos federales para apoyos funerarios.\n\n«Lamento mucho lo de la explosión, la pérdida de vidas humanas es la parte triste, la parte dolorosa, pero en lo general se demostró que podemos, entre todos, enfrentar los problemas más complejos y difíciles y ese es el ánimo que tenemos, estamos optimistas y así vamos a seguir enfrentando el gravísimo problema de la corrupción que no olvidemos es el principal problema de México», dijo el presidente Andrés Manuel López Obrador.\n", "url": "https://www.heraldo.mx/apoyo-a-victimas-de-tlahuelilpan-durara-todo-el-sexenio/"},
{"date": "2019-04-23T17:30:23-05:00", "title": "Ofrecen tratamiento médico de la resaca", "topic": "local", "text": "Opera en Aguascalientes la primera clínica para tratar la resaca, misma que ofrece diversas alternativas para aliviar hasta en 30 minutos las consecuencias de un día de excesos en la ingesta de alcohol. Se trata de ‘C.R.U.D.A, Clínica de Rehidratación de Urgencias para Desintoxicación y Atletas’, ubicada en el centro comercial de segundo anillo y avenida Independencia.\n\nEl Dr. Octavio González, responsable de la clínica, señala que una vez que el paciente ingresa, se le hace un chequeo general para conocer el grado de intoxicación que presenta y a partir de ahí se recomienda el tipo de servicio.\n\nPor menos de cien pesos, al paciente se le entrega un kit que contiene medicamento acorde a los síntomas que presente, además de vitaminas, rehidratación oral y energizante. Ese tratamiento se puede iniciar en casa y tiene un tiempo de respuesta de 45 minutos.\n\nExiste también el servicio que al igual que las vitaminas y los sueros, ofrece oxígeno para el paciente y hasta tratamiento intravenoso, que va acompañado de oxígeno, así como medicamento, vitaminas y bebidas rehidratantes. En este caso, la persona que experimenta los estragos de la resaca, queda lista en media hora para continuar con sus actividades.\n\nOctavio Giménez explicó que el atender de manera incorrecta la también conocida como ‘cruda’, ocasiona dolores de cabeza, escalofríos, mareos y vómito, ocasionado incluso una mayor deshidratación entre las personas. Recomendó no experimentar con ‘tratamientos populares’ como el ingerir alimentos picosos o aún más alcohol y evitar a toda costa automedicarse.\n\n“Lo ideal desde luego es no llegar a la intoxicación etílica, que se manifiesta por medio del vómito, cuando esto sucede significa que la persona consumió en exceso”, señaló.\n\nLa resaca depende de cada persona, del tipo de bebida que se haya ingerido, la complexión física y hasta la edad. Actualmente a la clínica acuden en su mayoría hombres en edad productiva, pero también mujeres y personas adultas.\n\nLa clínica también ofrece servicios para atender golpes de calor e intoxicaciones alimentarias.\n", "url": "https://www.heraldo.mx/ofrecen-tratamiento-medico-de-la-resaca/"},
{"date": "2019-04-23T10:04:29-05:00", "title": "Alcanza la violencia a menores de edad", "topic": "nacional", "text": "CIUDAD DE MÉXICO.- La escalada de violencia de los últimos meses en México ha alcanzado también a menores de edad.\n\nEl ataque a balazos el domingo pasado en contra de dos mujeres en el municipio de Comalcalco, Tabasco, dejó a dos menores heridos, entre ellos un bebé.\n\nEn la multiejecución en Minatitlán, Veracruz, registrada el 19 de abril, murió un bebé de un año que fue atacado de manera directa.\n\nLo mismo ocurrió en la agresión contra comensales de un restaurante en Cuautla, Morelos, el pasado 13 de abril, donde tres menores de edad fueron parte de las seis víctimas mortales.\n\nJuan Martín Pérez, director ejecutivo de la Red por los Derechos de la Infancia en México (Redim), advirtió que menores son cada vez más blanco de ejecuciones y actos de barbarie.\n\n«Estos casos muestran que hace ya mucho tiempo perdió cualquier respeto a la vida de un niño, una niña, y por otra parte, la terrible impunidad: de cada 100 carpetas de investigación donde menores son víctimas de algún delito, sólo una alcanza sentencia condenatoria.\n\n«No hay ninguna estrategia, ninguna política, no hay absolutamente nada para poder no sólo actualizar el diagnóstico de las violencias, sino construir una política de Estado. Lo que nos venden son espejitos, un programa, una declaración, una acción específica que no alcanza», advirtió.\n\nSegún datos de la Redim, de 2007 a 2017 se cometieron al menos 14 mil asesinatos de menores, un promedio de 3 víctimas al día.\n\nSólo en 2017, último año del que se tienen cifras oficiales, murieron por homicidio 51 menores de un año.\n\nCifras del Inegi indican que ese año también fueron asesinados 101 niños de 1 a 4 años; 69 de 5 a 9 años; 234 de 10 a 14 y 2 mil 403 jóvenes de 15 a 19 años de edad.\n", "url": "https://www.heraldo.mx/alcanza-la-violencia-a-menores-de-edad/"},
{"date": "2019-04-23T09:06:46-05:00", "title": "Llegan miles de Scouts a Aguascalientes", "topic": "local", "text": "Cerca de 2,700 jóvenes entre 10 y 14 años de edad de todo el país se dan cita al Camporee Nacional de Tropas 2019, organizado por la Asociación de Scouts de México del 23 al 27 de abril en Calvillo, Aguascalientes, informó el Jefe Scout nacional, Pedro Díaz Maya.\n\nEn conferencia de prensa, destacó que el Camporee 2019 tiene como objetivo fortalecer el programa educativo scout a través de actividades que promueven el trabajo en equipo, liderazgo, apreciación y cuidado de la naturaleza, sana competencia, potencializar las capacidades físicas y mentales de los scouts y promover la hermandad scout.\n\nComentó que en dicho campamento nacional se brinda a los más de 2 mil participantes la experiencia de competir sanamente, participar en concursos, realizar talleres, fortalecer la vida al aire libre y la técnica scout, convivir alrededor de una fogata; a lo largo de una caminata, siempre en compañía de amigos entrañables, además de conocer la cultura del Pueblo Mágico de Calvillo.\n", "url": "https://www.heraldo.mx/llegan-miles-de-scouts-a-aguascalientes/"},
{"date": "2019-04-23T09:46:34-05:00", "title": "Transparenta PNT sueldos de funcionarios", "topic": "nacional", "text": "CIUDAD DE MÉXICO 22-Apr-2019 .-La Plataforma Nacional de Transparencia (PNT) contiene la información de 24.3 millones de registros principales referidos a los sueldos y salarios de todos los servidores públicos que trabajan en el País.\nEsta información, de acuerdo con datos del Instituto Nacional de Transparencia, Acceso a la Información y Protección de Datos Personales (INAI), pertenecen a poco más de ocho mil sujetos obligados de los tres niveles de Gobierno, así como de los órganos autónomos.\nEntre la información que está consultable, se encuentra la remuneración bruta y neta, el nombre del servidor público, la denominación del cargo, el área de adscripción, las percepciones adiciones y su periodicidad, las gratificaciones recibidas, las primas, las comisiones, las dietas, bonos y prestaciones económicas y en especie otorgadas.\nToda esta información, que escala a 441.9 millones de registros, varía entre un poder y otro, por ejemplo, en el caso de la Federación, el total de registros es de 69.8 millones.\nEl pasado 14 de abril, la Secretaria de la Función Pública, Irma Eréndira Sandoval, dio a conocer el portal Nómina Transparente, con el cual el Gobierno Federal abrió la nómina de 1.4 millones de servidores públicos, incluidos los maestros.\nEn este portal se puede consultar el sueldo bruto y neto de los servidores públicos federales, y como información adicional permite conocer la institución para la que trabajan y el puesto que desempeñan.\nLas percepciones salariales son una de las 170 obligaciones de transparencia que las autoridades deben informar a los ciudadanos establecida en la Ley General de Transparencia y Acceso a la Información Pública.\nEn el caso de la PNT, la aplicación permite descargar la información en formato Excel o bien en archivos CSV sin límite de registros, para que los datos puedan ser utilizados y analizados por cualquier persona.\n", "url": "https://www.heraldo.mx/transparenta-pnt-sueldos-de-funcionarios/"},
{"date": "2019-04-23T10:08:42-05:00", "title": "Reconoce IMSS deficiencias", "topic": "nacional", "text": "CDMX.- El IMSS tiene una infraestructura instalada ineficiente, lo que origina un bajo número de camas disponibles e insuficiencia de personal médico y enfermería, afirmó Flavio Cienfuegos Valencia, director de Administración de la dependencia.\nIndicó que por cada mil habitantes la OCDE sugiere 3.3 camas, y el IMSS tiene un indicador de 1.1 camas por cada mil habitantes.\nSeñaló que el promedio de la OCDE es de 3.3 médicos por cada mil habitantes, y en el IMSS es de 1.8.\nIndicó que por cada mil habitantes la OCDE sugiere 9.1 personas en el área de enfermería. Por cada mil afiliados el IMSS tiene 2.3.\nEsto genera que el tiempo de espera de consulta externa sean del doble respecto al promedio nacional.\nEn 2018, indicó, el tiempo de consulta externa a nivel nacional fue de 23.1 minutos; en tanto que para el IMSS fue de 47.2 minutos.\nAfirmó que existen hospitales y unidades médicas saturadas, en condiciones poco funcionales o en mal estado.\nEjemplo son los siete hospitales dañados por los sismos de 2017, cuya rehabilitación no se ha concluido después de 18 meses y en la cual se han gastado 394.7 millones de pesos.\nDurante su comparecencia ante la Comisión de Salud del Senado, aseguró que el atraso en la atención y la deficiencia en el tratamiento provoca que los derechohabientes de asistir al IMSS eroguen recursos propios para su atención.\nPor ejemplo, en 2018, 26.6 millones de personas afiliadas necesitaron servicios de salud y sólo acudió el 43 por ciento asistió al IMSS.\nEl gasto de bolsillo promedio por persona fue de 2 mil 116 pesos al año en farmacias y consultorios privados, lo que representa 24 mil de millones de pesos por el total de personas que no acudieron.\n", "url": "https://www.heraldo.mx/reconoce-imss-deficiencias/"},
{"date": "2019-04-23T10:05:24-05:00", "title": "Afecta desorden en caso Minatitlán", "topic": "nacional", "text": "VERACRUZ, Veracruz.- La descoordinación entre el Gobierno de Veracruz y la Fiscalía General del estado ya afectaron la investigación de la masacre ocurrida Minatitlán el pasado viernes.\n\nLas diferencias políticas entre el Gobernador Cuitláhuac García y el Fiscal Jorge Winckler llevaron a que incluso la prensa supiera primero el nombre de dos presuntos vinculados al ataque armado donde murieron 13 personas, entre ellas un bebé.\n\nEl domingo, el Secretario de Seguridad Pública, Hugo Gutiérrez Maldonado, informó de dos «objetivos» ligados a la masacre.\n\n«Ya hay objetivos en la mira, se han logrado identificar a algunas personas de los cuales dos ya manejamos como objetivos. La investigación va muy adelantada. Todos (los involucrados en el crimen) están ligados a un grupo de la delincuencia organizada», refirió el funcionario.\n\nDe esos dos presuntos objetivos, el Fiscal Winkler no estaba enterado, al grado de que ayer pidió a Maldonado entregar información veraz de esos supuestos involucrados para solicitar a un juez las órdenes de aprehensión.\n\nLos alias que fueron ventilados a la prensa son «El Lagarto» y «El Pelón», operadores del Cártel de Jalisco Nueva Generación (CJNG).\n\n«Por los testigos sabemos la fisonomía de los atacantes, su vestimenta, pero hasta el momento no tenemos ningún apodo o nombre, si Seguridad Pública los tiene identificados le vamos a solicitar la informática», reprochó Winckler.\n\nDesde el viernes la SSP del estado desplegó sin éxito a decenas de elementos en Minatitlán y Coatzacoalcos en busca de los responsables de la masacre.\n\nA la par, elementos de la Fiscalía se abocaron a solicitar grabaciones de cámaras de seguridad, principalmente de empresas, pues las de las autoridades locales no funcionan.\n\nEl Gobernador se comprometió ayer a detener a los culpables de la masacre y evitar que se escapen, aunque dijo que es responsabilidad de Winckler determinar quiénes son.\n\n«De que se resuelve se resuelve, a pesar del Fiscal. Esperamos que el Fiscal acelere las investigaciones para que determine quiénes son los culpables y nosotros vayamos por ellos, no se van a escapar», dijo el mandatario en entrevista.\n\nEn tanto, la Fiscalía indicó que detrás del crimen de 13 personas en Minatitlán hay una pugna entre cárteles por el cobro de piso y el narcomenudeo.\n\n«Nosotros vamos a pedir al Fiscal que asista en una de las reuniones donde nos pueda informar cuál es el avance de sus investigaciones, porque está en el ámbito de su competencia», dijo García.\n\nEn medio de la racha de inseguridad y la descoordinación entre autoridades del Gobierno estatal y la Fiscalía, el Presidente Andrés Manuel López Obrador defendió la labor del García y consideró «un error» que, dijo, el ex mandatario Miguel Ángel Yunes haya impuesto a Winckler por nueve años en el cargo.\n\n«Ésta fue una práctica común durante el imperio de la corrupción, donde se protegían unos a otros.\n\n«El hecho de que lo haya dejado el Gobernador anterior y que esté actuando en protección del viejo régimen llama mucho la atención», señaló.\n\nEn contraste, levantó la mano a García y reiteró que es honesto.\n\n«Tiene todo el apoyo, todo el respaldo del Gobierno federal, y le tenemos confianza porque es una gente honesta», aseguró.\n", "url": "https://www.heraldo.mx/afecta-desorden-en-caso-minatitlan/"},
{"date": "2019-04-23T10:12:21-05:00", "title": "Robo de combustible disminuyó 90%, asegura AMLO", "topic": "nacional", "text": "El presidente Andrés Manuel López Obrador y el director de Pemex, Octavio Romero, expusieron los resultados de la estrategia implementada por el Gobierno de la República contra el huachicoleo.\n\nEn los últimos tres meses, el robo de combustible ha disminuido más del 90 por ciento, al pasar de los 56 mil barriles diarios a 4 mil.\n\nDe acuerdo a cifras expuestas por el titular de Petróleos Mexicanos, el robo de gasolinas Magna, Premium y Diesel, equivale al consumo diario de nueve estados (Aguascalientes, Baja California, Campeche, Colima, Durango, Querétaro, Quintana Roo, Tlaxcala y Zacatecas).\n\nLópez Obrador, señaló que las estrategias contra la extracción ilegal de combustibles continuarán hasta erradicar por completo dicho delito. De momento, más de 8 kilómetros de ductos han sido reforzados con concreto para evitar alteraciones en los mismos.\n\n“Si se pudo con el huachicol se puede con todo, vamos bien, estamos bien y de buenas… llevamos ahorrados 12 mil millones de pesos, de seguir con esta disminución en robo de gasolina, vamos a poder ahorrarnos alrededor de 50 mil millones de pesos”, resaltó.\n\nFinalmente el presidente reconoció la participación de elementos del ejército, Marina y Policía Federal, quienes se han sumado a las estrategias contra el huachicol.\n", "url": "https://www.heraldo.mx/robo-de-combustible-disminuyo-90-asegura-amlo/"},
{"date": "2019-04-23T09:50:15-05:00", "title": "Dan plazo para regular actividades vulnerables", "topic": "nacional", "text": "CIUDAD DE MÉXICO.- El Servicio de Administración Tributaria (SAT) publicó en el Diario Oficial de la Federación (DOF) las disposiciones para la autorregularización de actividades vulnerables.\n\nLas disposiciones publicadas ayer por el fisco establecen los procedimientos que deben cumplir los contribuyentes para la prevención e identificación de operaciones con recursos de procedencia ilícita del periodo del 1 de julio de 2013 al 31 de diciembre de 2018.\n\n«El SAT no impondrá sanciones por el periodo antes establecido, siempre y cuando se corrijan de todas las irregularidades o incumplimientos de las obligaciones al momento de haberse realizado la actividad vulnerable», afirma la autoridad fiscal.\n\nAñade que los contribuyentes deberán obtener la autorización en el Sistema del Portal en Internet de Lavado de Dinero manifestando su voluntad de corregir y subsanar las irregularidades u omisiones que se hayan realizado en el periodo mencionado.\n\nUna vez que la solicitud haya sido aceptada por la autoridad fiscal, se tienen seis meses para subsanar las irregularidades o incumplimientos, detalló vía comunicado.\n\nPosteriormente, durante los siguientes 20 días hábiles se podrá solicitar al Servicio de Administración Tributaria, a través de un escrito, la condonación de las multas que hayan sido impuestas en ese periodo, se informó.\n", "url": "https://www.heraldo.mx/dan-plazo-para-regular-actividades-vulnerables/"},
{"date": "2019-04-23T01:32:06-05:00", "title": "Deben entrar al quite los gobiernos locales", "topic": "local", "text": "En los primeros cuatro meses del año, tiempo en que el Gobierno Federal suspendió todos los programas para los emprendedores, capacitación, asistencia técnica, equipamiento y financiamiento, las empresas de menor tamaño han entrado a una etapa debilidad ante la competencia y de contracción del mercado, informó el director del CIDE, Alberto Aldape Barrios.\nHoy en día, el crédito productivo ofrece tasas de interés de 11% a los clientes de los bancos, mientras que ese porcentaje sube hasta 18% si se relaciona con empresas de menor tamaño. Sin embargo, el problema es el tiempo de respuesta que se tardan los bancos en aprobar o rechazar el crédito, el cual puede llevarse hasta seis semanas, cuya situación deja fuera de mercado a las Pymes.\nEl analista financiero aseveró que en este año ha quedado demostrado que los tiempos de la Federación no son los mismos que los del sector productivo. Aún así se espera que pronto la Secretaría de Economía presente sus programas en apoyo de las empresas de menor tamaño.\n“Se espera que los gobiernos estatales a través de sus áreas de desarrollo económico generen programas de apoyo económico similares a los que en su momento ofreció el desaparecido Inadem, a fin de alentar la actividad en la población emprendedora y las empresas de menor tamaño que necesitan capacitación y equipamiento para competir en el mercado”.\nEl director del Centro de Investigación y Desarrollo Empresarial señaló que como consecuencia de estas ausencias de apoyo financiero y capacitación se ha dado una menor generación de empleo al compararse este primer trimestre contra igual periodo del año 2018.\nAseveró que el ritmo de la actividad económica continúa frenándose al no haber tampoco los apoyos crediticios bancarios vía Nacional Financiera. Aldape Barrios agregó que la banca comercial se encuentra siendo selectiva en los clientes que puede apoyar con créditos, donde se solicita a los empresarios y emprendedores garantías que respalden el financiamiento solicitado.\nFinalmente, señaló que las tasas de interés bancarias en crédito hipotecario son accesibles y oscilan de 9.5 a 14%, gracias a la ventaja de que cuentan con la garantía que es el propio inmueble, cuyo valor crece a través del tiempo. Los plazos de pago van hasta 20 o 30 años.\n", "url": "https://www.heraldo.mx/deben-entrar-al-quite-gobiernos-locales/"},
{"date": "2019-04-23T01:33:16-05:00", "title": "Se complica el abasto de agua", "topic": "local", "text": "En esta temporada de calor, la Comisión Ciudadana de Agua Potable y Alcantarillado reportó una cobertura del 95% en el suministro del vital líquido y los tandeos ocurren por maniobras y fallas de pozos, fugas y por vandalismo a la infraestructura, lo que obliga a enviar este recurso de una colonia a otra, intentando reducir las molestias que eso genera.\nJosé Refugio Muñoz de Luna, director de la CCAPAMA, informó que este 2019 se invertirán cerca de 24 millones de pesos para obras de reposición de tuberías, rehabilitaciones y ampliación de red para solucionar problemas de fugas, con lo cual se podrá incrementar entre un 10 y 15% la eficiencia física.\nEn entrevista con El Heraldo, el funcionario precisó que este proyecto que se encuentra en proceso de licitación pública involucra 18 obras con diferentes alcances y diámetros. Detalló que los recursos provienen del Ramo 33 y serán ejecutados directamente por la CCAPAMA, cuyos dineros fueron aprobados por el Cabildo de Aguascalientes y los recursos ya se encuentran en la Secretaría de Finanzas del Municipio.\n Para este año, la empresa concesionaria Veolia deberá invertir en este concepto un monto de 40 millones de pesos, donde los recursos se canalizan hacia aquellos espacios que son necesarios para eficientar el servicio de agua potable y alcantarillado.\n En lo que va de la administración se acumulan 251 actos de vandalismo hacia la infraestructura de agua potable y alcantarillado, en algunos lugares son muy constantes en equipos de bombeo, rebombeo, válvulas, cables, elevadores y diversos componentes, donde el impacto económico oscila desde mil a un millón de pesos. Una de las formas de enfrentar esta problemática, es mediante 35 cámaras que se instalarán en los espacios con mayor índice de vandalismo, cuyo equipo de videovigilancia se enlazará con el C4 para actuar con oportunidad.\n", "url": "https://www.heraldo.mx/se-complica-el-abasto-de-agua/"},
{"date": "2019-04-23T01:34:25-05:00", "title": "Invitan a reflexionar para evitar tragedias", "topic": "local", "text": "Con el objetivo de evitar que jóvenes asistentes a la Feria de San Marcos, abusen de la ingesta de bebidas alcohólicas y puedan poner en riesgo su integridad, autoridades estatales a través del Instituto Aguascalientense de la Juventud (IAJU), pusieron en marcha la campaña denominada “En la Feria, Modera tus Tragos”.\nDicha campaña contempla la realización de actividades recreativas, buscando crear conciencia sobre los riesgos que implica beber altas cantidades de alcohol, además de pruebas de alcoholímetro voluntarias.\nEl titular del IAJU, Enrique Franco Medina, explicó que “el objetivo es informar claramente a los feriantes los peligros para la salud que representa consumir bebidas alcohólicas sin moderación y combinarlas con el volante”. Además, el Consejo Interuniversitario Contra las Adicciones (CICA), así como dependencias de los sectores sociales y salud, aplicarán pruebas de alcoholimetría a voluntarios que se encuentren disfrutando de la verbena, para que conozcan su estado actual y consideren no manejar un auto de regreso a su hogar.\nEn los dos primeros días de fiesta se aplicaron 210 pruebas de alcoholimetría a voluntarios que se encontraban en la Feria Nacional de San Marcos y se invitó a miles de jóvenes más a designar a un conductor que no tuviera un grado alto de alcohol, como principal acción preventiva de accidentes.\n", "url": "https://www.heraldo.mx/invitan-a-reflexionar-para-evitar-tragedias/"},
{"date": "2019-04-23T01:40:26-05:00", "title": "Costo, valor y arquitectura", "topic": "columnas", "text": "Darian Leader (1965- ) psicoanalista y ensayista británico sobre el arte y la cultura menciona en su obra El robo de la Monalisa. Lo que el arte nos impide ver, que el famoso cuadro de Leonardo da Vinci (1452-1519) realmente no tiene precio, y no lo tiene porque realmente no hay un mercado para esa pintura, no está a la venta y la única manera de hacerse de ella es hurtándola como sucedió a principios del siglo XX por el italiano, pintor de brocha gorda, Vincenzo Peruggia (1881-1947), quien deseaba regresar la pieza a su país y al verse imposibilitado para hacerlo decidió -tras dos años de mantener en su posesión la obra- finalmente venderla al director de la Galleria degli Uffizi, Alfredo Geri, quien al principio incrédulo de que el italiano poseyese verdaderamente la pintura original, le delató a las autoridades francesas que así recuperaron el famoso retrato para restituirlo a las colecciones del museo del Louvre.\n\nComo no hay un mercado para una obra así -su hipotético poseedor sólo podría disfrutarla a solas y de manera ultra secreta, como el mismo Peruggia que la mantuvo escondida en un baúl debajo de su cama apenas sacándola de su escondite unas pocas veces-, no hay precio de venta; la obra no tiene un precio comercial, pero es indudable que su valor real no tiene nada que ver con dinero.\n\nEn materia arquitectónica hay varias vías para valorar el precio de un edificio. Desde el costo del suelo y la cantidad de metros cuadrados construidos -pasando por la naturaleza de sus materiales y procesos constructivos- hasta sus características más subjetivas que tienen que ver con su carga artística, patrimonial, estilística, entre otras. Pero el valor genuino de un inmueble, si es que lo tiene, radica más en su naturaleza representativa que en el rendimiento de su uso o la cantidad de su mantenimiento, remozamiento o de su demolición-reconstrucción.\n\nDurante siglos las edificaciones de la Roma imperial fueron utilizadas como bando de materiales constructivos para todo tipo de las recientes fincas que se levantaban. En el siglo XVIII, las “vistas” de la ciudad de Roma realizadas por arquitecto, arqueólogo, investigador y grabador italiano Giovanni Battista Piranesi (1720-1778) mostraban las entonces recién redescubiertas ruinas romanas rodeadas de un paisaje bucólico con cabras y campesinos deambulando por lo que quedaba de esos vestigios majestuosos. Para los hombres de ese siglo Ilustrado, lo que estaba empezando era una revaloración del pasado clásico antiguo como fuente de un conocimiento seminal que estaba apuntalando a la intelectualidad del mundo Moderno. Lo que esos antiguos edificios y conjuntos representaban era la filiación occidental con un pasado luminoso que estaba siendo resucitado para iniciar un episodio nuevo en la Historia de la Humanidad.\n\nAl desplomarse un inmueble, cae con él un pedazo de historia o un fragmento de crónica local. No todo lo que se demuele posee ese valor testimonial, de hecho la mayor parte de lo que se derriba vale la pena ser abatido esperando que lo que lo sustituya sea mucho mejor. Sin embargo cuando lo que se tira tiene cierto valor arquitectónico y testimonial -a más de ser un edificio que ha soportado el paso de décadas en relativo buen estado-, quienes gustamos de disfrutar de nuestra ciudad y sus edificios, contenemos la respiración esperando que la obra sustituta esté a la altura al menos, de la que poseía el bloque que se echó abajo.\n\nEs comprensible que los propietarios de bienes inmuebles traten de potenciar su inversión y eso es señal de que la economía local mantiene una salud respetable, pero la renta económica proporcionada por un edificio, muchas veces no es sinónima del valor que ese mismo edificio posee como una referencia de lugar.\n\nEn dibujo se presenta una casa tipo chalet de fachada Art Déco que ya no existe. El deterioro de su contexto inmediato era ya evidente desde hace años y esta finca era una de las piezas que a pesar de su evidente envejecimiento, aún manifestaba su dignidad original. Esperando que lo que sustituya al inmueble tirado sea mucho mejor, sólo resta mencionar que no es lo mismo valor que precio. Algo costoso no siempre es comparable a algo de valor y viceversa. El valor tiene más que ver con el aprecio de algo por su mera presencia referencial, por su capacidad de representar una época, una manera de concebir lo que la sociedad es y fue, así como de vivir nuestro entorno como algo propio y no ajeno, al margen de que los edificios que nos acompañan en el diario no son de nuestra propiedad en su gran mayoría.\n\nComo se colige de lo expuesto, las fincas que aún permanecen en el perímetro del Primer Cuadro citadino, son en su gran mayoría dignas de preservarse por el valor plástico y espacial que tienen, sin embargo, también hay que tener en mente que muchas de ellas van siendo demolidas, perdiendo una parte de la imagen urbana de nuestra urbe acalitana.\n", "url": "https://www.heraldo.mx/costo-valor-y-arquitectura/"},
{"date": "2019-04-23T01:35:58-05:00", "title": "Revés para candidatos de Morena", "topic": "local", "text": "Por no fundamentar y motivar sus candidaturas, el Tribunal Electoral del Estado de Aguascalientes (TEEA) revocó el dictamen sobre este proceso interno de Morena, emitido el pasado 10 de abril.\nPor unanimidad de los tres Magistrados, se le ordenó a Morena emitir un nuevo dictamen sobre la elección de sus abanderados para los 11 Ayuntamientos, que además de estar fundamentado en su normatividad, contenga el resultado de sus encuestas.\n«Se revoca la resolución intrapartidista CNHJ-AGS-235/19, como consecuencia se deja sin efectos el dictamen de fecha 10 de abril emitido por el CEN, así como la resolución intrapartidista CNHJ-AGS-233/19», ordenó el Magistrado presidente, Héctor Salvador Hernández Gallegos.\nEn el proyecto de la magistrada Claudia Eloísa Díaz de León González se explicó que, pese a esta revocación, los perfiles ya elegidos podrán seguir en campaña electoral hasta que el nuevo documento dicte lo opuesto.\n«Se propone revocar el dictamen. Se le da una temporalidad para que dicte un nuevo dictamen, lo someta a consideración del CEN, y el resultado de ese dictamen sea el que se inscriba en el Instituto Estatal Electoral», argumentó la ponente.\n«Las candidaturas que el día de hoy están registradas, y que ya están haciendo campaña subsisten, hasta en tanto no haya una determinación del partido que diga lo contrario, una determinación del Comité Ejecutivo Nacional que diga lo contrario.\n«Si resulta que del dictamen hay una coincidencia con los candidatos que ya fueron aprobados por los órganos del Consejo Nacional, se queda así, y siguen adelante. Si hay una diferencia, se ordena al partido local que lo registre».\nPese a la coincidencia de criterios, el Magistrado Jorge Ramón Díaz de León Gutiérrez pidió que el fallo no fuera para todas las candidaturas, pues las impugnaciones solo las hicieron precandidatos de Asientos, San Francisco de los Romos, Pabellón de Arteaga y Tepezalá.\n«Sólo especifico que no debería ser en todos los Municipios, sino sólo en los cuatro que los precandidatos presentaron impugnaciones», precisó.\nTras el fallo, el CEN de Morena tendrá un plazo de 48 horas para presentar su nueva lista de perfiles políticos.\nUn caso similar ocurrió en Puebla, donde el Tribunal Electoral del Poder Judicial de la Federación (TEPJF) ordenó este mismo procedimiento sobre la candidatura de Miguel Barbosa al Gobierno de Puebla.\nPor su parte el Pleno de la Sala Regional Monterrey del TEPJF sesionó horas más tarde y en su resolución emitida sobre el mismo tema, coincidió en cuanto a que el procedimiento para el registro de las candidaturas de MORENA no fue conforme a derecho y se precisó que los órganos facultados para emitir el dictamen final del listado de candidaturas, son el Comité Ejecutivo Nacional y el órgano competente del dicho partido.\nPor lo tanto, emitió sentencia respecto a las y los ciudadanos que se inconformaron con la relación y el registro de candidaturas ante el Instituto Estatal Electoral. Ante ello, los magistrados resolvieron que se deja sin efecto la designación de candidaturas efectuadas por el Comité Directivo Estatal de MORENA y ordena al CEN y al órgano competente que procedan conforme a lo resuelto por dicho órgano y vincula a los Consejos Municipales y al Consejo General del IEE para que se pronuncien sobre la procedencia de los registros.\n", "url": "https://www.heraldo.mx/reves-a-candidatos-de-morena/"},
{"date": "2019-04-23T01:38:26-05:00", "title": "Escalpelo 23 de Abril", "topic": "columnas", "text": "UN DÍA DE LOCOS vivió el Partido MORENA en Aguascalientes, luego de las resoluciones del Tribunal Local y la Sala Regional de Monterrey en torno a su listado de candidaturas, donde ambos órganos piden al CEN reponer el procedimiento y anexar la encuesta que soporte su listado… AL CONOCER LA RESOLUCIÓN de la Sala Monterrey, donde los magistrados dejan sin efecto la designación de candidaturas efectuadas por el Comité Directivo Estatal de MORENA en Aguascalientes, el secretario de Organización del partido, Fernando Alférez Barbosa afirmó que aún tienen la posibilidad de impugnar dicho dictamen, sin embargo, reconoció que la pelota está prácticamente en la cancha del CEN de su partido… SERÁ ESTA INSTANCIA quien deberá reponer el proceso. Si bien el Comité Nacional tiene un plazo de 48 horas para resolver el listado correcto, Alférez confía en que por la importancia del asunto, es probable que quede definido este mismo martes… “EL CAMINO MÁS CORTO es que el CEN se reúna y de manera inmediata reponga. Una vez que sepamos cómo queda el listado y cómo resuelve el asunto el Comité Ejecutivo Nacional de MORENA, nosotros, en el Comité Directivo Estatal, habremos de emitir un nuevo pronunciamiento al respecto”… MIENTRAS TANTO, por la mañana de ayer lunes, también Luis Salazar -quien fuera uno de tantos aspirantes a candidato de MORENA por la presidencia municipal de Aguascalientes- anunció su renuncia a continuar en dicho partido político… LAMENTÓ LA SITUACIÓN por la que atraviesa en estos momentos el partido de López Obrador en la entidad en donde hay peleas continuas… YA ENTRADO en gastos, responsabilizó de esta situación al actual dirigente, Cuitláhuac Cardona Campos, por lo que consideró que las luchas internas han debilitado la candidatura de Arturo Ávila… TRAS DICHA DECLARACIÓN, el secretario de Organización, Fernando Alférez Barbosa, en rueda de prensa desestimó el anuncio de dicho personaje, afirmando que nunca se afilió a MORENA… “SI LUIS SALAZAR se queja de que MORENA no le hizo caso, es porque él salió como una imposición de Ricardo Monreal, la justicia y la razón pondrá en su lugar a cada quien”… DESDE EL CUARTEL de la avenida Independencia, los panistas no se quedaron callados ante las declaraciones de Arturo Ávila y Cardona Campos, quienes reaccionaron ante lo decidido tanto en el Tribunal de la calle Juan de Montoro como en la Sala Regional Monterrey del TEPJF culpando a los panistas… EL LÍDER ESTATAL, Gustavo Báez Leos respondió a los morenistas asegurando que el partido que encabeza en la entidad “está concentrado en la victoria de las próximas elecciones” y pidió Cardona Campos “que primero arregle su cochinero y después siga diciendo sus mentiras, y para eso le quedan menos de 48 horas”… DEBATE DE ALTURA, sin duda… DEJAMOS LOS DIMES Y DIRETES de las contiendas políticas para pasar al terreno de la verbena y el desparpajo, donde el escenario pinta bonito para los ruleteros, a pesar del lamentable asalto que sufriera uno de ellos y que le costara la vida… SEGÚN EL PRESIDENTE de la Sociedad Unidos de Operadores de Taxis de Aguascalientes, Francisco Javier Pacheco Méndez, los trabajadores del volante se encuentran porque se encuentran ocupados día y noche… DESDE LA PERSPECTIVA de este gremio es notable la presencia de visitantes foráneos quienes los mantienen del tingo al tango… TAMBIÉN HAY BUENAS NOTICIAS para los amantes de las gorditas fritas en manteca, los perros calientes de carrito y otros antojos callejeros que abundan en la zona ferial, pues saldo blanco arrojó el operativo implementado por el área de Regulación Sanitaria, durante el primer fin de semana de feria… CON ESTE OPERATIVO se tenía el objetivo de llevar a cabo la ubicación de alimentos y bebidas en mal estado. El titular de la Comisión para la Protección Contra Riesgos Sanitarios del Estado, Octavio Jiménez indicó que en esta ocasión no se encontraron anomalías que pudieran poner en riesgo la salud de los consumidores… SIN EMBARGO, no se vale dormirse en los laureles, y al tratarse de los primeros días de verbena, los trabajos deberán de continuar bajo el mismo tenor, esperando que continúe el correcto entendimiento con los vendedores… EL FUNCIONARIO ACLARÓ que en caso de que las autoridades sanitarias detecten alimentos en mal estado, así como alcohol adulterado, se procederá conforme marca la ley, es decir, con el aseguramiento y destrucción del producto, además de sanciones administrativas y hasta clausuras, dependiendo de la gravedad del asunto… Y PARA TERMINAR con los asuntos feriales, un apunte sobre la congruencia y la legalidad que celebramos… CON MANO DURA y en estricto cumplimiento a la Ley de Vialidad, agentes viales han comenzado a trabajar en el perímetro ferial, infraccionando a todos aquellos conductores que no respeten espacios prohibidos para tal fin… TAL ES EL CASO de la multa levantada contra el oficial de la patrulla 0979-B1 de la Policía Municipal, quien creyó que por traer un auto oficial podría estacionarse a un costado de un contenedor de basura… AL FINAL, los agentes viales hicieron su trabajo demostrando que la ley se debe respetar sin distinción alguna. Bien por esta decisión. O todos coludos, o todos rabones, diría el abuelo… DOS VOCES NOS RECORDARON que ayer se celebró el “Día Internacional de la Madre Tierra”, como sucede desde hace 48 años… POR UN LADO, la fecha fue recordada por Mauricio Romero Lara, gerente de Veolia, quien hizo una serie de recomendaciones para darle cariño y consuelo a nuestro planeta, la casa de todos… APUNTÓ QUE BAÑARSE optimizando el uso de agua es una de las alternativas; una sugerencia para garantizar su abasto es cerrar las llaves mientras se enjabonan; y colocar una o dos cubetas que capten el agua que cae de la regadera, para reaprovechar ese recurso para trapear o para circular los desechos del inodoro… “AUNQUE EL 71% de la superficie terrestre está cubierta por agua, según la Organización Mundial de la Salud (OMS), en una ducha de 10 minutos se consumen 200 litros de agua, demasiada para el aseo diario recomendado”, aseveró… TAMBIÉN HIZO UN LLAMADO a depositar las pilas usadas en los contenedores para estos fines que se encuentran en supermercados y tiendas de conveniencia: si una de estas baterías que usamos cotidianamente no es eliminada correctamente y llega al mar, los metales pesados contenidos en ella pueden llegar a contaminar hasta 3 mil litros de agua. Además, el mercurio que contienen es uno de los elementos químicos más tóxicos para el planeta…. OTRA DE LAZ VOCES que hizo énfasis en el día de la Madre Tierra fue Gina Mireya Ventura Ramírez, presidenta del Instituto Mexicano de Estudios de Posgrado, quien afirmó que el grave problema de Aguascalientes sigue siendo el agua y la erosión del suelo… APÚNTÓ QUE SI BIEN hay acciones de reforestación, también hay deforestaciones, por lo que las autoridades y la gente deben procurar plantar árboles que sean nativos de la región que permitan también recargar los mantos freáticos y atacar con ello la sequía que hay… “SE DEBEN PLANTAR MEZQUITES y huizaches que son de aquí, porque se está arborizando, no reforestando, están poniendo árboles que crecen rápido, y que lucen muy bien ahorita, pero que requieren mucha agua”… LAS VENTAJAS de reforestar con especies navitas es que con ellas se puede generar un microclima y atraer lluvias, apuntó…\n", "url": "https://www.heraldo.mx/escalpelo-23-de-abril-3/"},
{"date": "2019-04-23T01:41:27-05:00", "title": "¡Se los dije!", "topic": "columnas", "text": "Esa parece ser la exclamación del ingeniero geólogo Arturo Sotelo Rodríguez, que por casi treinta años ha insistido en que la ciudad capital puede sufrir un movimiento telúrico de consecuencias, al encontrarse asentada en un espacio propicio para este tipo de fenómenos, algo que se vivió hace unos días, que aún cuando fue leve el movimiento dejó viviendas agrietadas y un susto para quienes vivieron el momento.\n\nEn un programa de radio calificó de neófitos a funcionarios estatales y municipales, lo mismo que a los ingenieros civiles y arquitectos, que sin los conocimientos suficientes declararon que fue algo pasajero, por lo que no había razón para que hubiera alarma entre la población.\n\nArturo Sotelo es, por decirlo así, la “oveja negra” en la investigación que tienen lugar sobre las fallas geológicas, por lo que las autoridades se niegan a recibirlo y cuando tiene la oportunidad de presentar sus investigaciones no se le da seguimiento, sin embargo, lo anotado recientemente le da la razón y bien harían en ambos palacios al conocer sus puntos de vista y que sean analizados por conocedores de este asunto, inclusive invitar a investigadores de la UNAM y el Politécnico para que den su opinión, con lo que habría la solidez necesaria para llevar a cabo las acciones que correspondan.\n\nLo más importante que hace el Comité Interinstitucional de Fallas Geológicas y Grietas del Estado es actualizar el atlas respectivo, porque, según el titular de la Seguot, Armando Roque, se pretende informar “oportunamente” la ruta de las fallas y en su caso, las ramificaciones que se detecten.\n\nLa cuestión está en ir más allá y quedar prevenidos de lo que pueda ocurrir, no ahora ni mañana sino a futuro, con lo que se podrá evitar o mitigar una contrariedad y es algo que ha venido estudiando Arturo Sotelo.\n\nLo que ocurre no es, de ninguna manera, algo nuevo, tan es así que a mediados del siglo pasado el famoso Dr. IQ preguntó en su programa radial que transmitió desde aquí, que cuál era la “ciudad hueca” y como nadie supo responder al final dijo que era Aguascalientes, que en el aquel tiempo se creía que las grietas y fallas eran parte de los túneles o pasadizos que periódicamente se descubrían en alguna vivienda o en un baldío.\n\nSe tiene documentado que en el estado hay 220 fallas y 24 grietas con una longitud de 315.6 kilómetros. Pasan por 2 mil 528 inmuebles, de los cuales 1,864 están afectados por las fallas, 306 dañados no atribuibles a las fallas y sin daños 358.\n\nEsta situación se registra en casi todos los municipios. En Aguascalientes son 75 fallas y cinco grietas; Rincón de Romos presenta 25 fallas y tres grietas; Pabellón de Arteaga, 36 fallas y cinco grietas; Cosío, 16 fallas y cinco grietas; Asientos, tres fallas y cinco grietas; Jesús María, 47 fallas y seis grietas; San Francisco de los Romo, 12 fallas y una grieta, y Tepezalá, cinco fallas y dos grietas. Calvillo, San José de Gracia y El Llano no presentan fallas ni grietas.\n\nAunque las leyes estatales y municipales prohíben construir sobre el recorrido de una falla o grieta, es difícil predecir el aparecimiento posterior de alguna falla en donde ya está edificado, por lo que tendrán que aplicarse modelos constructivos similares a los que ya operan en la capital del país.\n\nSi el geólogo Sotelo tiene décadas de lanzar la voz de alerta, es tiempo de que dejen de hacer oídos sordos y conozcan qué plantea, con lo que juntamente con lo que tengan otras instancias se pueda atender ahora, un problema que pueda surgir.\nNEGOCIO REDITUABLE\nDesde los tiempos bíblicos se tenía al Díos Baco como uno de los principales invitados a cualquier festejo, porque sin él no había ambiente, algo que hasta la fecha sigue haciéndose, por lo que el supremo gobierno de todo país y reino sabe que ahí está una mina de oro que nunca se acaba, a través de los impuestos y cobros que aplica, muy por encima de cualquier otro negocio que tiene una inversión superior.\n\nEl municipio de Aguascalientes registra casi 900 mil habitantes, por lo que es normal que entre las actividades comerciales tenga un número elevado de lugares donde se vende y consume bebidas alcohólicas, que es aprovechado por las autoridades locales para obtener ingresos más allá de los normales, cuestión que se debe a que sobran personas que desean abrir un negocios de estas características.\n\nPara ello tiene 4 mil 500 licencias reglamentadas divididas en 57 modalidades y que operan en distintos rumbos, principalmente en la zona Centro (Venustiano Carranza, Moctezuma, Madero, Zaragoza, Nieto y Hornedo, entre otras), lo mismo que en avenida Luis Donaldo Colosio, Las Américas y Alameda.\n\nPara tener derecho a este tipo de negocios hay que pagar, por apertura, 170 mil 237 pesos para un merendero; bar, 177 mil 509 pesos; cabaret de primera, 221 mil 840 pesos; cabaret de segunda, 189 mil 351 pesos; cabaret de tercera, 158 mil 274 pesos; cantina 124 mil 248 pesos; centro nocturno 207 mil pesos; bar y centro nocturno, 377 mil 103 pesos.\n\nDe igual forma, en un hotel con restaurante-bar 377 mil 103 pesos y hotel con bar y discoteca 288 mil 417 pesos. En plaza de toros y espectáculos públicos con aforo hasta por 21 mil personas 221 mil 348 pesos y con aforo hasta por 5 mil personas 70 mil 055 pesos; salón de baile con espectáculo 422 mil 253 pesos; palenque con espectáculo 251 mil 444 pesos y venta de cerveza, cerradas en negocios, 11 mil 116 pesos.\n\nNadie escapa de pagar lo que impone el Gobierno Municipal, por lo que en centros de apuestas, por cada mesa de juego debe pagarse 21 mil 840 pesos y 10 mil 920 pesos por cada maquinita; estadio para futbol con venta de cerveza, 313 mil 048 pesos; estadio de beisbol profesional con venta de cerveza, 191 mil 623 pesos; carreras de vehículos motorizados Nascar o similar en el Óvalo de Aguascalientes, 319 mil 372 pesos.\n\nLo descrito es sólo una parte de los gastos que deben hacer los interesados, porque viene el acondicionamiento del local, el mobiliario, la compra de enseres, contratación y pago de personal, etc., sin embargo es un negocio muy perseguido, lo que demuestra que mientras existan consumidores habrá quién arriesgue su capital y que por regla general, casi todos permanecen en el lugar o se mueven a otro, pero no claudican.\n\nEs indudable que la deidad mitológica del vino sabe repartir sus favores a quienes promueven su veneración, por lo que hay quienes tienen dos o más negocios dedicados a esa supremacía, no obstante lo que tenga que gastar cada año para la renovación de la licencia o permiso.\nLO TIENE EN ASCUAS\nAunque el presidente Andrés Manuel López Obrador dijo que está en desacuerdo con que estados y municipios paguen por el apoyo y los servicios que aporte la Guardia Nacional en los lugares donde vaya a operar, para el presidente municipal de Jesús María, Ags., Noel Mata Atilano, terminará el desconcierto hasta que se publique la ley de este organismo, que en la propuesta enviada al Senado aparece con esa obligación. Es un problema económico que, de darse, impactará los ingresos del lugar, por lo que está a la espera de que se elimine ese apartado de la iniciativa.\n", "url": "https://www.heraldo.mx/se-los-dije/"},
{"date": "2019-04-23T08:47:57-05:00", "title": "No dejaremos a los 'Pueblos Mágicos' a su suerte: López Martín", "topic": "local", "text": "A pesar de que el Gobierno de la República encabezado por Andrés Manuel López Obrador, estableció eliminar el apoyo económico para los Pueblos Mágicos en todo el país, el secretario de Turismo, Jorge López Martín, aseguró que se harán esfuerzos por mantener el funcionamiento de los tres Pueblos con los que cuenta el estado.\n\nEl funcionario señaló que la idea es respaldar los Pueblos Mágicos ubicados en Calvillo, Real de Asientos y San José de Gracia, además de los diversos sitios turísticos con los que cuenta Aguascalientes.\n\n“El gobernador ha sido muy claro en seguir fortaleciendo los Pueblos Mágicos. Por lo tanto, el Gobierno del Estado (los) seguirá apoyando”.\n\nEl funcionario agregó que la instrucción es ser dinámicos ante este reto y buscar alternativas a esta crisis presupuestaria. López Martín destacó: “hasta este momento nosotros lo hemos venido resolviendo con nuevas estrategias para seguir difundiendo no solamente los Pueblos Mágicos, sino los diferentes sitios turísticos con los que cuenta el estado”, precisó.\n\nLópez Martínez dijo que se aprovecharán las ferias en cada municipio para posicionar turísticamente a Aguascalientes, acciones que irán fortalecidas con convenios de aerolíneas quienes darán tarifas preferenciales. “No tenemos tiempo para quejarnos. Nos estamos poniendo a trabajar para ir fortaleciendo el turismo local”, sentenció.\n", "url": "https://www.heraldo.mx/no-dejaremos-a-los-pueblos-magicos-a-su-suerte-lopez-martin/"},
{"date": "2019-04-23T01:51:08-05:00", "title": "Falsos servidores públicos roban datos personales", "topic": "local", "text": "Alerta la delegación de la Secretaría de Bienestar a no dejarse sorprender por personas ajenas a la dependencia que se hacen pasar por empleados del Gobierno Federal, en el intento de obtener información confidencial de la ciudadanía durante esta temporada de veda electoral.\nEl delegado Estatal de Programas de Desarrollo Integral en Aguascalientes, Aldo Ruiz Sánchez comentó que desde el inicio de las campañas electorales se han presentado algunas denuncias ciudadanas en el sentido de que gente ajena a la Secretaría de Bienestar con identificaciones y vestimenta presuntamente apócrifa se hacen pasar por empleados del Gobierno Federal, en el intento de obtener información confidencial de la ciudadanía.\nAnte estos hechos, el funcionario federal hizo un atento llamado a toda la ciudadanía, a fin de evitar que sean engañados y brinden cualquier tipo información que pueda poner en riesgo su integridad y patrimonio personal o familiar. En tal sentido, enfatizó que la Secretaría de Bienestar refrenda su compromiso con la población y la democracia, para actuar en absoluto apego a lo que la ley le ordena con el objetivo de dar certeza y transparencia al proceso electoral, así como evitar que se altere el orden y la tranquilidad social.\nAsimismo, aclaró que con el fin de salvaguardar el clima de estabilidad e imparcialidad durante el desarrollo del proceso electoral que se realiza en Aguascalientes, la Secretaría de Bienestar implementó un Programa de Blindaje Electoral desde el pasado 15 de abril y que tendrá vigencia hasta el próximo 3 de junio.\nDetalló que dicho programa contempla una serie de acciones a las que deben sujetarse estrictamente los servidores públicos, sobre todo aquellos que están directamente involucrados en la operación de programas sociales, razón por la que el personal que labora en la dependencia recibió capacitación por parte de la Secretaría de la Función Pública y las áreas de control interno de la propia dependencia federal, con la que se impedirá incurrir en prácticas ilícitas.\n“Se determinó hacer una pausa en la entrega de apoyos sociales, a fin de garantizar la legitimidad de los programas y recursos de la Federación, fortalecer los principios de equidad y legalidad durante el proceso electoral, así como evitar que los apoyos se utilicen con fines ajenos al bienestar social”, finalizó.\n", "url": "https://www.heraldo.mx/falsos-servidores-publicos-roban-datos-personales/"},
{"date": "2019-04-23T08:57:14-05:00", "title": "Invitan a reflexionar para evitar tragedias", "topic": "local", "text": "Con el objetivo de evitar que jóvenes asistentes a la Feria de San Marcos abusen de la ingesta de bebidas alcohólicas y puedan poner en riesgo su integridad, autoridades estatales a través del Instituto Aguascalientense de la Juventud (IAJU), pusieron en marcha la campaña denominada “En la Feria, Modera tus Tragos”.\n\nDicha campaña contempla la realización de actividades recreativas, buscando crear conciencia sobre los riesgos que implica beber altas cantidades de alcohol, además de pruebas de alcoholímetro voluntarias.\n\nEl titular del IAJU, Enrique Franco Medina, explicó que “el objetivo es informar claramente a los feriantes los peligros para la salud que representa consumir bebidas alcohólicas sin moderación y combinarlas con el volante”. Además, el Consejo Interuniversitario Contra las Adicciones (CICA), así como dependencias de los sectores sociales y salud, aplicarán pruebas de alcoholimetría a voluntarios que se encuentren disfrutando de la verbena, para que conozcan su estado actual y consideren no manejar un auto de regreso a su hogar.\n\nEn los dos primeros días de fiesta se aplicaron 210 pruebas de alcoholimetría a voluntarios que se encontraban en la Feria Nacional de San Marcos y se invitó a miles de jóvenes más a designar a un conductor que no tuviera un grado alto de alcohol, como principal acción preventiva de accidentes.\n", "url": "https://www.heraldo.mx/invitan-a-reflexionar-para-evitar-tragedias-2/"},
{"date": "2019-04-23T00:42:35-05:00", "title": "Se escaparon dos menores del hospicio", "topic": "policiacas", "text": "Unos niños que se fugaron de una casa-hogar en el municipio de Teocaltiche, Jalisco, fueron localizados deambulando en las inmediaciones de la Central Camionera.\n\nLos policías estatales detectaron a dos niños de 10 años que deambulaban sin rumbo fijo y desorientados sobre la vía de Quinta Avenida esquina con la calle República de Guatemala.\n\nAl presumir que estaban extraviados decidieron interceptarlos para tratar de ayudarlos. En ese momento se descubrió que los dos pequeños originarios del municipio de San Juan de los Lagos y se habían escapado de la Casa Hogar “Madre de los Dolores”, ubicada en el municipio de Teocaltiche, Jalisco, por lo que fueron asegurados y trasladados a Trabajo Social del Complejo de la SSPM.\n", "url": "https://www.heraldo.mx/se-escaparon-dos-menores-del-hospicio/"},
{"date": "2019-04-23T00:37:44-05:00", "title": "Perdieron el camino", "topic": "policiacas", "text": "Una camioneta que circulaba a exceso de velocidad por una terracería se salió del camino cuando el conductor perdió el control y terminó por caer a un desnivel. El saldo fue de dos personas lesionadas.\n\nEste accidente se registró el lunes a las 10:39 de la mañana, a la altura del kilómetro 0+850 del camino de terracería que conduce de la colonia Adolfo López Mateos al Panteón “San Pablo”, en el poblado de Cañada Honda.\n\nHasta ese lugar llegaron policías estatales, quienes encontraron la camioneta accidentada, siendo una Titán pick up, color blanco y placas de circulación del estado de Arizona, Estados Unidos.\n\nLas personas lesionadas fueron el conductor identificado como J. Reyes, de 58 años y una mujer de nombre Josefina, de 28 años. A bordo de la ambulancia UE-12 de la Coordinación Municipal de Protección Civil de Aguascalientes, fueron trasladados a recibir atención médica al Hospital Tercer Milenio, donde se reportó su estado de salud como estable.\n", "url": "https://www.heraldo.mx/perdieron-el-camino/"},
{"date": "2019-04-23T00:39:37-05:00", "title": "Mortal accidente en Universidad", "topic": "policiacas", "text": "Espantosa muerte sufrió un joven motociclista al impactarse brutalmente contra la parte trasera de una pipa que se disponía a regar con agua el camellón central de avenida Universidad. Fue identificado como Luis Fernando, de 19 años, con domicilio en la colonia El Mezquital, en el municipio de Jesús María. El accidente se registró el lunes a las 17:20 horas, a la altura del fraccionamiento Bosques del Prado.\n\nEl joven tripulaba una motocicleta Italika, modelo 2017, color rojo y placa de circulación Y34-UE de Aguascalientes. Se desplazaba a exceso de velocidad por el carril central de avenida Universidad en sentido de sur a norte y al llegar a la altura de la calle Andes Apeninos intentó rebasar un coche Chevrolet Spark y se cambió al carril izquierdo.\n\nSin embargo, la maniobra la realizó sin precaución y no se percató que metros adelante estaba detenido un camión tipo pipa marca International, modelo 2006, color blanco, con número económico 2356 y placas de circulación AE-2232-A de Aguascalientes, conducido por el empleado municipal Manuel Alejandro, de 31 años, con domicilio en el fraccionamiento Solidaridad I.\n\nFue tan sorpresivo lo ocurrido que el motociclista no alcanzó a frenar y chocó de lleno contra la parte trasera de la pipa. A pesar de llevar puesto el casco de protección, de nada le sirvió pues murió de manera instantánea ante el brutal impacto.\n\nAl lugar del accidente arribaron policías preventivos del Destacamento “Pocitos”, policías viales, una ambulancia de Coordinación Municipal de Protección Civil, agentes del Grupo Homicidios de la PME, personal de la Dirección de Investigación Pericial y el agente del MP de Hospitales.\n", "url": "https://www.heraldo.mx/mortal-accidente-en-universidad/"},
{"date": "2019-04-23T00:40:27-05:00", "title": "Frenaron su intento de suicidio", "topic": "policiacas", "text": "Por causas desconocidas un hombre intentó suicidarse el domingo pasado en el municipio de El Llano, aunque sus intenciones fueron frustradas por los mismos familiares y la oportuna intervención de policías preventivos.\n\nLos hechos se registraron a las 19:40 horas, en el poblado de El Retoño, cuando familiares del señor Salvador, de 49 años, lo encontraron en el interior de un automóvil estacionado, con un cincho de plástico atado al cuello. Ya esta persona comenzaba a sufrir los efectos de la asfixia, por lo que de inmediato cortaron el cincho para ponerlo a salvo. Posteriormente, policías preventivos de El Llano procedieron a estabilizarlo.\n\nMomentos después llegó también una ambulancia del ISSEA, cuyos paramédicos valoraron al señor Salvador y determinaron que no ameritaba su traslado a algún nosocomio. Cabe destacar que al momento de los hechos, esta persona se encontraba bajo los influjos de las bebidas alcohólicas.\n", "url": "https://www.heraldo.mx/frenaron-su-intento-de-suicidio/"},
{"date": "2019-04-23T00:43:32-05:00", "title": "Aparatoso incendio", "topic": "policiacas", "text": "Más de 50 toneladas de pastura fueron consumidas por el fuego tras registrarse un incendio en un rancho ubicado en el municipio de Calvillo. El siniestro también consumió otras 17 toneladas de pollinaza, un camión tipo torton y una plataforma, por lo que las pérdidas materiales ascienden a un millón de pesos.\n\nLos hechos se registraron en el rancho “Las Tranquilas”, que se ubica sobre la terracería que conduce al Rastro Municipal, justo en la parte posterior del panteón del poblado de El Cuervero. Todo se originó cuando el propietario del rancho de nombre Juan Antonio, decidió quemar basura. Sin embargo, el fuego se salió de control y alcanzó las pacas de pastura y pollinaza, así como el vehículo pesado y una plataforma antes descritos.\n\nAl lugar de los hechos arribaron policías estatales y policías preventivos, además de Bomberos Municipales de Calvillo y personal de Protección Civil Municipal que se dieron a la tarea de sofocar el siniestro. Luego de casi 50 minutos de intensos trabajos, el incendio fue controlado en su totalidad, aunque no se evitó que causara pérdidas millonarias.\n", "url": "https://www.heraldo.mx/aparatoso-incendio/"},
{"date": "2019-04-23T00:41:31-05:00", "title": "Se impactó contra un poste", "topic": "policiacas", "text": "Contra un poste de la CFE se impactó una camioneta en calles del fraccionamiento Pozo Bravo Norte. No hubo personas lesionadas y todo quedó en daños materiales por más de 10 mil pesos.\n\nEl percance se registró el domingo a las 20:30 horas, en la calle Pozo Hondo y casi cruce con avenida Pozo Bravo.\n\nSe estableció que al momento de los hechos, una camioneta marca Pontiac tipo vagoneta, color verde y con placas de circulación AFY-9978 de Aguascalientes, se desplazaba por avenida Pozo Bravo y al llegar a la esquina con la calle Pozo Hondo, el conductor dio vuelta hacia su derecha para incorporarse a la misma.\n\nPero la maniobra la realizó sin disminuir la velocidad, lo que provocó que perdiera el control y fuera a impactarse contra un poste de concreto de la CFE. Cuando llegaron patrullas de la Policía Vial encontraron la camioneta accidentada abandonada.\n", "url": "https://www.heraldo.mx/se-impacto-contra-un-poste/"},
{"date": "2019-04-23T00:44:50-05:00", "title": "Violento “viene viene”", "topic": "policiacas", "text": "Violento sujeto fue detenido en el área ferial, debido a que golpeó a un automovilista que se negó a darle dinero como “gratificación”, debido a que supuestamente estuvo cuidándole su vehículo. Los hechos se registraron el domingo a las 19:30 horas en la calle Nieto, en el perímetro de la Feria Nacional de San Marcos. El detenido fue identificado como Rogelio, de 65 años, quien con franela en mano, se dedicaba a pedir dinero a las personas con el pretexto de estar cuidando sus vehículos estacionados en la vía pública. Sin embargo, un automovilista se negó a tal petición, lo que provocó el coraje del señor Rogelio y arremetió contra él a golpes, siendo arrestado momentos después por policías preventivos de Aguascalientes que lo trasladaron a la Base “Volcán” de la SSPM, donde quedó a disposición del juez calificador.\n", "url": "https://www.heraldo.mx/violento-viene-viene/"},
{"date": "2019-04-23T00:46:59-05:00", "title": "Triple tragedia en volcadura", "topic": "policiacas", "text": "Saldo de tres muertos y un herido dejó la volcadura de una camioneta en la carretera federal No. 45 Norte, a la altura del municipio de Rincón de Romos.\n\nEl trágico accidente automovilístico se registró el lunes a las 15:40 horas, a la altura del poblado de El Salitrillo.\n\nLas personas que murieron fueron el conductor identificado como Alfonso, de 37 años; su acompañante de nombre José Manuel, de 45 años y un niño de 10 años, todos ellos con domicilio en el municipio de San Francisco de los Romo. Otro pequeño de 11 años resultó herido y fue trasladado al Hospital General de Rincón de Romos.\n\nViajaban en una camioneta Chevrolet S-10 pick up, color azul y placas de circulación de Aguascalientes. Debido a que se desplazaba a exceso de velocidad en sentido de norte a sur, el conductor perdió el control y se salió de la carretera, para después dar varias volteretas y terminar a más de 30 metros de la cinta asfáltica.\n\nAl momento de la volcadura salieron expulsados el niño y el señor José Manuel, quienes al caer al suelo fueron aplastados por la camioneta y murieron instantáneamente. El conductor quedó con medio cuerpo por fuera de la ventanilla y también murió aplastado.\n\nAl lugar del accidente arribaron policías preventivos de Rincón de Romos y policías estatales, Bomberos Municipales de Rincón de Romos, personal de Protección Civil y una ambulancia del ISSEA, a bordo de la cual el único sobreviviente fue trasladado a recibir atención médica. Asimismo, a fin de realizar las diligencias correspondientes, acudieron agentes del Grupo Homicidios de la PME, personal de la Dirección de Investigación Pericial y el agente del MP de Hospitales.\n", "url": "https://www.heraldo.mx/triple-tragedia-en-volcadura/"},
{"date": "2019-04-23T01:26:57-05:00", "title": "Mi candidatura está firme: Arturo Ávila", "topic": "local", "text": "Niega MORENA Aguascalientes que se haya quedado sin candidatos y por el contrario, avaló la resolución del Tribunal Local Electoral donde se pide al Comité Ejecutivo Nacional que exhiba la metodología de las encuestas para ratificar el listado de las candidaturas.\nEn conferencia de prensa, el representante Jurídico de MORENA en Aguascalientes, Alejandro Sánchez Laguna, aclaró que la resolución del Tribunal tiene que ver con los juicios de protección de quienes se sintieron agraviados al no quedar como candidatos, por lo cual, el Tribunal Local Electoral requiere al CEN para que en un plazo de 48 horas, exhiba la metodología de encuestas del listado de candidatos.\nPor su parte, el secretario de Organización del Comité Directivo Estatal, Fernando Alférez Barbosa, afirmó que ve improbable que haya modificaciones en la lista que presentó el Comité Directivo Estatal al IEE, ante la grave omisión en que cayó la Comisión Nacional de Elecciones, salvo de aquellos que sigan defendiendo con pruebas sus registros. “Nosotros no estamos descalificando a todos a priori, incorporamos a Arturo Ávila y a gente que milita en MORENA, en respeto al estatuto, que establece que las candidaturas se pueden otorgar hasta en un 50%. Fueron más de 200 candidatos. Celebramos que MORENA dé una señal inequívoca de que puede ganarle a la Derecha”.\nFinalmente, el abanderado a la Alcaldía de Aguascalientes, Arturo Ávila, aseveró que su candidatura está más firme que nunca y seguirán adelante en una campaña muy creativa y sin volanteo, toda vez que su nombre aparece tanto en la lista nacional como en la que presentó en su momento el Comité Directivo Estatal, por lo que culpó al PAN y al PRI de estar desesperados y tratar de confundir a la gente.\n“Hay los intereses de que siga permaneciendo un grupo en el poder, un grupo que ha buscado todo para que Arturo Ávila no llegue, porque vamos muy bien, de acuerdo a nuestros números. Están muy asustados porque saben que conmigo se les acabó el negocio, los moches, los acuerdos en lo oscurito, se trata de la mafia del PRIAN que están desesperados y tratando de confundir a la sociedad de Aguascalientes”, finalizó.\n", "url": "https://www.heraldo.mx/mi-candidatura-esta-firme/"},
{"date": "2019-04-23T01:30:02-05:00", "title": "Son tres los grandes dolores de cabeza en el municipio", "topic": "local", "text": "La inseguridad, el transporte público y los robos son los problemas que más preocupan a los ciudadanos del municipio de Aguascalientes, según un sondeo de opinión realizado por el Colegio de Economistas.\nEn conferencia de prensa, el presidente del Colegio, Jael Pérez Sánchez, dio a conocer el resultado de una encuesta que se desarrolló del 5 al 7 de abril pasado en 322 viviendas de los cuatro puntos cardinales del municipio de Aguascalientes. En primer término dijo que la primera pregunta fue sobre cuáles eran los principales problemas que tienen en el municipio. Los consultados respondieron así:\n \n \n \n Sobre la situación económica presente respecto a hace un año, comentó que el 35.9% de la gente dice que la economía está peor; el 46.4 considera que está igual de buena; y un 16.2% dice que está igual de mala. Asimismo, sobre la expectativa de la situación económica futura, destacó que un 30.4% afirma que va a estar igual de buena; un 27.2% de la población cree que va a mejorar la economía; y un 24.7% dice que la economía va a estar peor.\n En cuanto al tema de la inseguridad, destacó que el principal problema de inseguridad son los robos a casa habitación con un 26.2%, seguido de la falta de alumbrado público con el 8.4%, y el asalto a la vía pública con el 7.9%. Sobre la incidencia de los delitos, señaló que se le cuestionó a la gente sobre si han sido víctimas de algún delito y el 21.9% respondió afirmativamente, contra un 77.4% que no. Es decir, 2 de cada 10 personas han sido víctimas. Y de quienes han sido parte de un agravio, el 34.9% fue víctima de robo a casa habitación; el 26.6% dijo haber sido objeto de un asalto en la vía pública; y el robo de autopartes con un 21.7%.\n En cuanto a la calificación que la gente da a los distintos Servicios Públicos, destacan las siguientes cifras:\n \nFinalmente, dicho sondeo fue hecho con la intención de que quienes ahorita fungen como candidatos de los distintos partidos políticos, vean cuál es el sentir ciudadanos sobre las problemáticas más sentidas y enfoquen de mejor manera sus propuestas.\n", "url": "https://www.heraldo.mx/son-tres-los-grandes-dolores-de-cabeza-en-el-municipio/"},
{"date": "2019-04-23T00:33:47-05:00", "title": "Roba, huye y se estampa", "topic": "policiacas", "text": "Un presunto delincuente que conducía una camioneta que minutos antes había robado, resultó lesionado al impactarse contra un árbol, después de intentar escapar de policías estatales y policías preventivos de San Francisco de los Romo que iban en su persecución.\n\nQuien ya se encuentra a disposición del agente del Ministerio Público de la Unidad de Combate al Robo de Vehículos de la PME, es un individuo identificado como José Julio, de 20 años.\n\nTodo se originó cuando inicialmente se reportó el robo de una camioneta pick up, color negro y placas de circulación de Aguascalientes, en las inmediaciones del rancho “San Ángel”. De inmediato se implementó un operativo por parte de policías estatales y policías preventivos de San Francisco de los Romo, quienes momentos después detectaron la camioneta robada cuando circulaba por la calle Antonio Rodríguez, en el poblado de La Concepción.\n\nCuando el conductor se percató de la presencia de las patrullas intentó darse a la fuga, por lo que se inició una persecución que concluyó en la calle Emiliano Zapata, cuando el robacoches perdió el control de la camioneta y fue a impactarse brutalmente contra un árbol. Debido a que José Julio resultó con golpes en el rostro, al lugar del accidente acudió una ambulancia del ISSEA. Una vez que los paramédicos lo valoraron y brindaron los primeros auxilios, determinaron que no ameritaba su traslado a algún nosocomio, por lo que fue detenido y trasladado a la Fiscalía General del Estado.\n", "url": "https://www.heraldo.mx/roba-huye-y-se-estampa/"},
{"date": "2019-04-23T00:36:52-05:00", "title": "Intentaron matarlo a balazos", "topic": "policiacas", "text": "Durante la madrugada del lunes un hombre resultó herido a balazos después de que desconocidos intentaron ejecutarlo. El lesionado fue identificado como Luis Alberto, de 39 años, quien presentaba cuatro heridas de bala, dos de ellas en el antebrazo izquierdo, uno en la pierna izquierda y otro más en la cabeza, aunque se trató de sólo un rozón.\n\nLos violentos hechos se registraron el lunes a las 00:22 horas, en la avenida Próceres de la Enseñanza y esquina con avenida La Salud, en el fraccionamiento J. Guadalupe Peralta. La víctima fue atacada a balazos por dos sujetos desconocidos, cuando se encontraba frente a un negocio de venta de carnitas y chicharrones.\n\nLos agresores lo atacaron con una pistola tipo escuadra y después escaparon en un vehículo color rojo con rumbo al oriente de la ciudad. El lesionado fue trasladado a recibir atención médica a un nosocomio, a bordo de un automóvil Mazda, color negro.\n\nA la escena de la agresión llegaron inicialmente policías estatales en la patrulla AG915 y agentes de la Fiscalía General del Estado. Posteriormente, hizo su arribo un policía preventivo del Destacamento «Terán Sur», en la unidad 0091-B2. A pesar de que se montó un operativo por toda la zona, no se logró dar con el paradero de los sicarios. En la escena del ataque fueron localizados dos casquillos percutidos. Agentes del Grupo Homicidios de la PME ya se encuentran realizando las investigaciones correspondientes.\n", "url": "https://www.heraldo.mx/intentaron-matarlo-a-balazos/"},
{"date": "2019-04-23T00:28:22-05:00", "title": "Reparten sentencias por delitos federales", "topic": "policiacas", "text": "A tres años de prisión fue sentenciado por un juez de Control del Centro de Justicia Federal con sede en Aguascalientes, un individuo que fue encontrado culpable del delito contra la salud.\n\nLa Fiscalía General de la República en Aguascalientes, a través del agente del Ministerio Público, aportó los elementos de prueba suficientes para que el juez de Distrito sentenciara a 3 años de prisión a un individuo de nombre Óscar Arturo L., por el delito contra la salud en la modalidad de posesión simple de Clonazepam. Además, se le impuso una multa de 50 Unidades de Medida y Actualización (UMA).\n\nPor otra parte, una persona de nombre Juan Alberto R., fue sentenciado a un año y 4 meses de prisión, así como al pago de 50 UMAs, tras ser encontrado culpable del delito de portación de arma de fuego sin licencia. Fue detenido con una pistola tipo revólver calibre 38 Especial.\n", "url": "https://www.heraldo.mx/reparten-sentencias-por-delitos-federales/"},
{"date": "2019-04-23T00:32:43-05:00", "title": "Recuperan más de 20 vehículos", "topic": "policiacas", "text": "Varios vehículos con reporte de robo y con alteraciones en sus números de serie fueron recuperados por la Fiscalía General del Estado, durante una serie de operativos llevados a cabo por agentes del Grupo Localización de Vehículos de la PME. En total fueron recuperadas 23 unidades, de las cuales seis de ellas corresponden a reportes de robo.\n\nSe trata de un vehículo Nissan Tsuru, sin placas de circulación, que fue robado en la Ciudad de México y recuperado en el fraccionamiento Ojocaliente III; una camioneta Dodge Nitro, color blanco y con matrícula ABB-255-B de Aguascalientes, recuperada en la colonia Insurgentes; y un Nissan March, color blanco y con placas de circulación AED-776-B de Aguascalientes, localizado en el rancho “La Soledad”.\n\nUn coche Chevrolet Chevy Monza, color azul, con placas de circulación ABM-369-B de Aguascalientes, recuperado en el fraccionamiento Alborada, un automóvil VW Jetta, color arena, con matrícula ADK-939-B y un coche Ford Escort, color blanco y con placas de circulación MNF-9852 del Estado de México, estos dos últimos localizados en el Ejido Coyotes.\n\nMientras que por alteraciones en sus números de serie fueron asegurados 16 vehículos, entre los que destacan un Porsche Boxter, color negro y sin placas de circulación, asegurado en la colonia España; un coche Dodge Challenger, color blanco y con placas de circulación D68-ARN de la Ciudad de México, localizado en la colonia Del Trabajo; y una camioneta Toyota Sienna, color blanco y con matrícula D69-AYA de la Ciudad de México, recuperada en el fraccionamiento Rinconada Pozo Bravo.\n", "url": "https://www.heraldo.mx/recuperan-mas-de-20-vehiculos/"},
{"date": "2019-04-23T00:35:48-05:00", "title": "Los lesiona y les roba camioneta", "topic": "policiacas", "text": "Un peligroso sujeto fue capturado por policías preventivos de Aguascalientes, tras haber consumado el robo con violencia de una camioneta en calles del fraccionamiento Hacienda San Marcos. Durante el atraco, resultaron heridos el conductor y una mujer que le acompañaba.\n\nLos violentos hechos se registraron el domingo por la tarde, en el estacionamiento de una tienda de autoservicio ubicada en avenida Mariano Hidalgo, en el fraccionamiento Morelos II.\n\nUn hombre identificado como Hugo, se disponía abordar su camioneta Chevrolet Venture, modelo 1999, color blanco y placas de circulación ABF-784-B de Aguascalientes, pero en ese momento fue interceptado por un peligroso delincuente identificado como Israel, de 37 años, quien lo atacó con una manopla y le provocó una lesión en el rostro. Una mujer que acompañaba a la víctima, de nombre Irene, trató de ayudarlo pero resultó herida con un cuchillo en el hombro derecho.\n\nTras implementarse un operativo, el delincuente fue interceptado por policías preventivos del Destacamento “Morelos” en las patrullas 0047-B2 y 0810-A1 en la avenida Prolongación Héroe Inmortal y esquina con avenida Santoral, en el fraccionamiento Hacienda San Marcos.\n\nCabe destacar que en el lugar del atraco, el sospechoso dejó abandonada una motocicleta Italika Forza, modelo 2018, color rojo y matrícula XFB-1G de Aguascalientes, que cuenta con reporte de robo. Los lesionados fueron trasladados en una ambulancia de la Coordinación Municipal de Protección Civil a recibir atención médica al Hospital Tercer Milenio. Agentes del Grupo Localización de Vehículos de la PME, ya se encuentran realizando las investigaciones correspondientes.\n", "url": "https://www.heraldo.mx/los-lesiona-y-les-roba-camioneta/"}
]
\ No newline at end of file
# -*- coding: utf-8 -*-
# Define here the models for your scraped items # Define here the models for your scraped items
# #
# See documentation in: # See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html # https://docs.scrapy.org/en/latest/topics/items.html
import scrapy import scrapy
class NoticiasItem(scrapy.Item): class HeraldoagsItem(scrapy.Item):
# define the fields for your item here like: # define the fields for your item here like:
# name = scrapy.Field() # name = scrapy.Field()
date = scrapy.Field()
title = scrapy.Field() title = scrapy.Field()
text = scrapy.Field() text = scrapy.Field()
date = scrapy.Field()
location = scrapy.Field() location = scrapy.Field()
author = scrapy.Field() author = scrapy.Field()
topic = scrapy.Field() topic = scrapy.Field()
......
# -*- coding: utf-8 -*-
# Define here the models for your spider middleware # Define here the models for your spider middleware
# #
# See documentation in: # See documentation in:
# http://doc.scrapy.org/en/latest/topics/spider-middleware.html # https://docs.scrapy.org/en/latest/topics/spider-middleware.html
from scrapy import signals from scrapy import signals
# useful for handling different item types with a single interface
from itemadapter import is_item, ItemAdapter
class HeraldoagsSpiderMiddleware(object): class HeraldoagsSpiderMiddleware:
# Not all methods need to be defined. If a method is not defined, # Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the spider middleware does not modify the # scrapy acts as if the spider middleware does not modify the
# passed objects. # passed objects.
...@@ -20,30 +21,29 @@ class HeraldoagsSpiderMiddleware(object): ...@@ -20,30 +21,29 @@ class HeraldoagsSpiderMiddleware(object):
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened) crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s return s
def process_spider_input(response, spider): def process_spider_input(self, response, spider):
# Called for each response that goes through the spider # Called for each response that goes through the spider
# middleware and into the spider. # middleware and into the spider.
# Should return None or raise an exception. # Should return None or raise an exception.
return None return None
def process_spider_output(response, result, spider): def process_spider_output(self, response, result, spider):
# Called with the results returned from the Spider, after # Called with the results returned from the Spider, after
# it has processed the response. # it has processed the response.
# Must return an iterable of Request, dict or Item objects. # Must return an iterable of Request, or item objects.
for i in result: for i in result:
yield i yield i
def process_spider_exception(response, exception, spider): def process_spider_exception(self, response, exception, spider):
# Called when a spider or process_spider_input() method # Called when a spider or process_spider_input() method
# (from other spider middleware) raises an exception. # (from other spider middleware) raises an exception.
# Should return either None or an iterable of Response, dict # Should return either None or an iterable of Request or item objects.
# or Item objects.
pass pass
def process_start_requests(start_requests, spider): def process_start_requests(self, start_requests, spider):
# Called with the start requests of the spider, and works # Called with the start requests of the spider, and works
# similarly to the process_spider_output() method, except # similarly to the process_spider_output() method, except
# that it doesn’t have a response associated. # that it doesn’t have a response associated.
...@@ -54,3 +54,50 @@ class HeraldoagsSpiderMiddleware(object): ...@@ -54,3 +54,50 @@ class HeraldoagsSpiderMiddleware(object):
def spider_opened(self, spider): def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name) spider.logger.info('Spider opened: %s' % spider.name)
class HeraldoagsDownloaderMiddleware:
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the downloader middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_request(self, request, spider):
# Called for each request that goes through the downloader
# middleware.
# Must either:
# - return None: continue processing this request
# - or return a Response object
# - or return a Request object
# - or raise IgnoreRequest: process_exception() methods of
# installed downloader middleware will be called
return None
def process_response(self, request, response, spider):
# Called with the response returned from the downloader.
# Must either;
# - return a Response object
# - return a Request object
# - or raise IgnoreRequest
return response
def process_exception(self, request, exception, spider):
# Called when a download handler or a process_request()
# (from other downloader middleware) raises an exception.
# Must either:
# - return None: continue processing this exception
# - return a Response object: stops process_exception() chain
# - return a Request object: stops process_exception() chain
pass
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
# -*- coding: utf-8 -*-
# Define your item pipelines here # Define your item pipelines here
# #
# Don't forget to add your pipeline to the ITEM_PIPELINES setting # Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
import json
from collections import OrderedDict
class JsonWriterPipeline(object):
def __init__(self, filename):
self.filename = filename
@classmethod
def from_crawler(cls, crawler):
# Here you get whatever value was passed through the "filename" command line parameter
settings = crawler.settings
filename = settings.get('filename')
# Instantiate the pipeline with the file name # useful for handling different item types with a single interface
return cls(filename) from itemadapter import ItemAdapter
def open_spider(self, spider):
self.counter = 0
self.file = open(self.filename, 'w')
self.file.write("[")
def close_spider(self, spider):
self.file.write("]")
self.file.close()
class HeraldoagsPipeline:
def process_item(self, item, spider): def process_item(self, item, spider):
# print("this is my item", item)
row = []
try:
row.append(("date", item['date']))
except:
pass
try:
row.append(("topic", item['topic']))
except:
pass
try:
row.append(("title", item['title']))
except:
pass
try:
row.append(("author", item['author']))
except:
pass
try:
row.append(("location", item['location']))
except:
pass
try:
row.append(("text", item['text']))
except:
pass
try:
row.append(("url", item['url']))
except:
pass
line = OrderedDict(row)
self.counter += 1
if self.counter == 1:
self.file.write(json.dumps(line))
elif self.counter > 1:
self.file.write(",\n" + json.dumps(line))
return item return item
# -*- coding: utf-8 -*-
# Scrapy settings for heraldoAgs project # Scrapy settings for heraldoAgs project
# #
# For simplicity, this file contains only settings considered important or # For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation: # commonly used. You can find more settings consulting the documentation:
# #
# http://doc.scrapy.org/en/latest/topics/settings.html # https://docs.scrapy.org/en/latest/topics/settings.html
# http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html # https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
# http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html # https://docs.scrapy.org/en/latest/topics/spider-middleware.html
BOT_NAME = 'heraldoAgs' BOT_NAME = 'heraldoAgs'
SPIDER_MODULES = ['heraldoAgs.spiders'] SPIDER_MODULES = ['heraldoAgs.spiders']
NEWSPIDER_MODULE = 'heraldoAgs.spiders' NEWSPIDER_MODULE = 'heraldoAgs.spiders'
FEED_EXPORT_ENCODING="utf-8"
# Crawl responsibly by identifying yourself (and your website) on the user-agent # Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'heraldoAgs (+http://www.yourdomain.com)' #USER_AGENT = 'heraldoAgs (+http://www.yourdomain.com)'
# Obey robots.txt rules # Obey robots.txt rules
# ROBOTSTXT_OBEY = True ROBOTSTXT_OBEY = True
# Configure maximum concurrent requests performed by Scrapy (default: 16) # Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32 #CONCURRENT_REQUESTS = 32
# Configure a delay for requests for the same website (default: 0) # Configure a delay for requests for the same website (default: 0)
# See http://scrapy.readthedocs.org/en/latest/topics/settings.html#download-delay # See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs # See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.5 #DOWNLOAD_DELAY = 3
# The download delay setting will honor only one of: # The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16 #CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16 #CONCURRENT_REQUESTS_PER_IP = 16
# Disable cookies (enabled by default) # Disable cookies (enabled by default)
COOKIES_ENABLED = False #COOKIES_ENABLED = False
# Disable Telnet Console (enabled by default) # Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False #TELNETCONSOLE_ENABLED = False
...@@ -45,31 +43,31 @@ COOKIES_ENABLED = False ...@@ -45,31 +43,31 @@ COOKIES_ENABLED = False
#} #}
# Enable or disable spider middlewares # Enable or disable spider middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html # See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = { #SPIDER_MIDDLEWARES = {
# 'heraldoAgs.middlewares.HeraldoagsSpiderMiddleware': 543, # 'heraldoAgs.middlewares.HeraldoagsSpiderMiddleware': 543,
#} #}
# Enable or disable downloader middlewares # Enable or disable downloader middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html # See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = { #DOWNLOADER_MIDDLEWARES = {
# 'heraldoAgs.middlewares.MyCustomDownloaderMiddleware': 543, # 'heraldoAgs.middlewares.HeraldoagsDownloaderMiddleware': 543,
#} #}
# Enable or disable extensions # Enable or disable extensions
# See http://scrapy.readthedocs.org/en/latest/topics/extensions.html # See https://docs.scrapy.org/en/latest/topics/extensions.html
#EXTENSIONS = { #EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None, # 'scrapy.extensions.telnet.TelnetConsole': None,
#} #}
# Configure item pipelines # Configure item pipelines
# See http://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html # See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = { #ITEM_PIPELINES = {
'heraldoAgs.pipelines.JsonWriterPipeline': 300, # 'heraldoAgs.pipelines.HeraldoagsPipeline': 300,
} #}
# Enable and configure the AutoThrottle extension (disabled by default) # Enable and configure the AutoThrottle extension (disabled by default)
# See http://doc.scrapy.org/en/latest/topics/autothrottle.html # See https://docs.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True #AUTOTHROTTLE_ENABLED = True
# The initial download delay # The initial download delay
#AUTOTHROTTLE_START_DELAY = 5 #AUTOTHROTTLE_START_DELAY = 5
...@@ -82,7 +80,7 @@ ITEM_PIPELINES = { ...@@ -82,7 +80,7 @@ ITEM_PIPELINES = {
#AUTOTHROTTLE_DEBUG = False #AUTOTHROTTLE_DEBUG = False
# Enable and configure HTTP caching (disabled by default) # Enable and configure HTTP caching (disabled by default)
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings # See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True #HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0 #HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache' #HTTPCACHE_DIR = 'httpcache'
......
# -*- coding: utf-8 -*-
import scrapy, re
from heraldoAgs.items import NoticiasItem
"""
MEDIO:
El Heraldo, Aguascalientes
USO:
scrapy crawl noticias --nolog -s filename=2018-01-05.json -a year=2018 -a month=1 -a day=5
""" """
Spider for heraldo.mx
Author: Mario Chirinos Coluga
Usage:scrapy crawl noticias --nolog -O 2017-04-23.json -a year=2017 -a month=4 -a day=23
"""
import scrapy
import re
from heraldoAgs.items import HeraldoagsItem
#-------------------------------------------------------------------------------
TAG_RE = re.compile(r'<[^>]+>') TAG_RE = re.compile(r'<[^>]+>')
def remove_tags(text): def remove_tags(text):
return TAG_RE.sub('', text) return TAG_RE.sub('', text)
#-------------------------------------------------------------------------------
LOC_RE = re.compile(r'.+?(\d{1,2}-?[a-zA-Z]+)?\s?\.-\s?') class NoticiasSpider(scrapy.Spider):
DAT_RE = re.compile(r'\s?(\d{1,2}-?[a-zA-Z]+)?\s?\.-\s?') name = 'noticias'
allowed_domains = ['heraldo.mx']
start_urls = ['https://heraldo.mx/']
class QuotesSpider(scrapy.Spider): #-----------------------------------------------------------------------
name = "noticias"
def start_requests(self): def start_requests(self):
year = getattr(self, "year", None) year = getattr(self, "year", None)
month = getattr(self, "month", None) month = getattr(self, "month", None)
day = getattr(self, "day", None) day = getattr(self, "day", None)
self.date = year + "-" + month.zfill(2) + "-" + self.day.zfill(2)
self.baseURL = "http://www.heraldo.mx/" + year + "/" + month + "/" + day self.baseURL = "http://www.heraldo.mx/" + year + "/" + month + "/" + day
yield scrapy.Request(url=self.baseURL, callback=self.parsePage)
#-----------------------------------------------------------------------
def parsePage(self, response):
#print(response.url)
for i in response.xpath('//div[@class="td-ss-main-content"]//h3/a/@href').extract():
yield scrapy.Request(url=i, callback=self.parse_item, dont_filter=True)
yield scrapy.Request(url=self.baseURL, callback=self.parse) nextPage = response.xpath('//div[contains(@class,"page-nav")]/a[@aria-label="next-page"]/@href').extract_first()
if nextPage is not None:
yield scrapy.Request(url=nextPage, callback=self.parsePage)
def parse(self, response):
yield scrapy.Request(url=response.url, callback=self.parse_page, dont_filter=True)
lastPage = response.xpath('//*[@class="page-nav td-pb-padding-side"]/a[@class="last"]/text()').extract_first()
if lastPage is not None and lastPage != '':
lastPage = int(lastPage)
for page in range(1,lastPage):
yield scrapy.Request(url=self.baseURL + "/page/" + str(page+1), callback=self.parse_page)
def parse_page(self, response):
for link in response.xpath('//*[@class="td-block-row"]').css('h3').css('a::attr(href)').extract():
yield scrapy.Request(url=link, callback=self.parse_item)
# #-----------------------------------------------------------------------
def parse_item(self, response): def parse_item(self, response):
item = NoticiasItem() #print(response.url)
text = '' item = HeraldoagsItem()
"La fecha obtenida ya incluye formato y zona horaria"
item['date'] = response.xpath('//time[@class="entry-date updated td-module-date"]/@datetime').extract_first()
item['title'] = remove_tags(response.xpath('//header[@class="td-post-title"]/h1').extract_first())
item['topic'] = response.xpath('//ul[@class="td-category"]/li/a/text()').extract_first()
author = response.xpath('//pre[@style="text-align: justify;"]/text()').extract_first() item['date'] = response.xpath('//time[contains(@class, "entry-date")]/@datetime').extract_first()
if author is not None and author != '': item['title'] = response.xpath('//meta[@property="og:title"]/@content').extract_first()
item['author'] = " ".join(author.split("\n")[0].split()) item['topic'] = str(response.xpath('//li[@class="entry-category"]/a/text()').extract_first()).lower()
paragraphs = response.xpath('//div[contains(@class,"td-post-content")]/p/text()').extract()
text=""
for p in paragraphs:
p = p.replace("<br>", "\n")
text += remove_tags(p) + "\n"
bodyText = response.xpath('//*[@class="td-post-content"]/p').extract()
for i in range(0, len(bodyText)):
p = remove_tags(bodyText[i])
if i <= 1:
p = p.lstrip()
result = LOC_RE.match(p)
if result:
item['location'] = DAT_RE.sub('', result.group(0))
p = LOC_RE.sub('', p)
text += p + "\n"
item['text'] = text item['text'] = text
item['url'] = response.url item['url'] = response.url
print(item["title"])
yield item yield item
# Automatically created by: scrapy startproject # Automatically created by: scrapy startproject
# #
# For more information about the [deploy] section see: # For more information about the [deploy] section see:
# https://scrapyd.readthedocs.org/en/latest/deploy.html # https://scrapyd.readthedocs.io/en/latest/deploy.html
[settings] [settings]
default = heraldoAgs.settings default = heraldoAgs.settings
......
...@@ -9,9 +9,9 @@ import scrapy ...@@ -9,9 +9,9 @@ import scrapy
class LajornadaItem(scrapy.Item): class LajornadaItem(scrapy.Item):
# define the fields for your item here like: # define the fields for your item here like:
# name = scrapy.Field() # name = scrapy.Field()
date = scrapy.Field()
title = scrapy.Field() title = scrapy.Field()
text = scrapy.Field() text = scrapy.Field()
date = scrapy.Field()
location = scrapy.Field() location = scrapy.Field()
author = scrapy.Field() author = scrapy.Field()
topic = scrapy.Field() topic = scrapy.Field()
......
...@@ -15,8 +15,8 @@ def remove_tags(text): ...@@ -15,8 +15,8 @@ def remove_tags(text):
class NoticiasSpider(scrapy.Spider): class NoticiasSpider(scrapy.Spider):
name = 'noticias' name = 'noticias'
allowed_domains = ['jornada.com.mx'] allowed_domains = ['jornada.com.mx']
start_urls = ['http://jornada.com.mx/'] start_urls = ['https://jornada.com.mx/']
section_list = ["politica", "mundo", "capital", "cultura", "deportes", "economia", "sociedad", "estados", "espectaculos"] section_list = ["politica", "mundo", "capital", "ciencias", "cultura", "deportes", "economia", "sociedad", "estados", "espectaculos"]
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def start_requests(self): def start_requests(self):
year = getattr(self, "year", None) year = getattr(self, "year", None)
...@@ -25,8 +25,13 @@ class NoticiasSpider(scrapy.Spider): ...@@ -25,8 +25,13 @@ class NoticiasSpider(scrapy.Spider):
self.date = year + "-" + month.zfill(2) + "-" + self.day.zfill(2) self.date = year + "-" + month.zfill(2) + "-" + self.day.zfill(2)
self.baseURL = "https://www.jornada.com.mx/" + year + "/" + month.zfill(2) + "/" + self.day.zfill(2) + "/" self.baseURL = "https://www.jornada.com.mx/" + year + "/" + month.zfill(2) + "/" + self.day.zfill(2) + "/"
for s in self.section_list: yield scrapy.Request(url=self.baseURL, callback=self.parseSectionList)
yield scrapy.Request(url=self.baseURL + s, callback=self.parseSection) #-----------------------------------------------------------------------
def parseSectionList(self, response):
link_set = [ i for i in response.css('div.main-sections').css('a::attr(href)').extract() if len(i)>len("/XXXX/XX/XX/") and i != "https://www.jornada.com.mx/sinfronteras"]
for i in link_set:
yield scrapy.Request(url=self.start_urls[0]+i[1:], callback=self.parseSection)
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def parseSection(self, response): def parseSection(self, response):
link_set = set(response.css('div.section-cont').css('a.cabeza::attr(href)').extract()) link_set = set(response.css('div.section-cont').css('a.cabeza::attr(href)').extract())
......
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class NoticiasItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
text = scrapy.Field()
date = scrapy.Field()
location = scrapy.Field()
author = scrapy.Field()
topic = scrapy.Field()
url = scrapy.Field()
# -*- coding: utf-8 -*-
# Define here the models for your spider middleware
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/spider-middleware.html
from scrapy import signals
class LarazonSpiderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the spider middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_spider_input(response, spider):
# Called for each response that goes through the spider
# middleware and into the spider.
# Should return None or raise an exception.
return None
def process_spider_output(response, result, spider):
# Called with the results returned from the Spider, after
# it has processed the response.
# Must return an iterable of Request, dict or Item objects.
for i in result:
yield i
def process_spider_exception(response, exception, spider):
# Called when a spider or process_spider_input() method
# (from other spider middleware) raises an exception.
# Should return either None or an iterable of Response, dict
# or Item objects.
pass
def process_start_requests(start_requests, spider):
# Called with the start requests of the spider, and works
# similarly to the process_spider_output() method, except
# that it doesn’t have a response associated.
# Must return only requests (not items).
for r in start_requests:
yield r
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
import json
from collections import OrderedDict
class JsonWriterPipeline(object):
def __init__(self, filename):
self.filename = filename
@classmethod
def from_crawler(cls, crawler):
# Here you get whatever value was passed through the "filename" command line parameter
settings = crawler.settings
filename = settings.get('filename')
# Instantiate the pipeline with the file name
return cls(filename)
def open_spider(self, spider):
self.counter = 0
self.file = open(self.filename, 'w')
self.file.write("[")
def close_spider(self, spider):
self.file.write("]")
self.file.close()
def process_item(self, item, spider):
# print("this is my item", item)
row = []
try:
row.append(("date", item['date']))
except:
pass
try:
row.append(("topic", item['topic']))
except:
pass
try:
row.append(("title", item['title']))
except:
pass
try:
row.append(("author", item['author']))
except:
pass
try:
row.append(("location", item['location']))
except:
pass
try:
row.append(("text", item['text']))
except:
pass
try:
row.append(("url", item['url']))
except:
pass
line = OrderedDict(row)
self.counter += 1
if self.counter == 1:
self.file.write(json.dumps(line))
elif self.counter > 1:
self.file.write(",\n" + json.dumps(line))
return item
# -*- coding: utf-8 -*-
# Scrapy settings for laRazon project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
# http://doc.scrapy.org/en/latest/topics/settings.html
# http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
# http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html
BOT_NAME = 'laRazon'
SPIDER_MODULES = ['laRazon.spiders']
NEWSPIDER_MODULE = 'laRazon.spiders'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'laRazon (+http://www.yourdomain.com)'
# Obey robots.txt rules
# ROBOTSTXT_OBEY = True
# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32
# Configure a delay for requests for the same website (default: 0)
# See http://scrapy.readthedocs.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.5
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16
# Disable cookies (enabled by default)
COOKIES_ENABLED = False
# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False
# Override the default request headers:
#DEFAULT_REQUEST_HEADERS = {
# 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
# 'Accept-Language': 'en',
#}
# Enable or disable spider middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
# 'laRazon.middlewares.LarazonSpiderMiddleware': 543,
#}
# Enable or disable downloader middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
# 'laRazon.middlewares.MyCustomDownloaderMiddleware': 543,
#}
# Enable or disable extensions
# See http://scrapy.readthedocs.org/en/latest/topics/extensions.html
#EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None,
#}
# Configure item pipelines
# See http://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'laRazon.pipelines.JsonWriterPipeline': 300,
}
# Enable and configure the AutoThrottle extension (disabled by default)
# See http://doc.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True
# The initial download delay
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False
# Enable and configure HTTP caching (disabled by default)
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
# This package will contain the spiders of your Scrapy project
#
# Please refer to the documentation for information on how to create and manage
# your spiders.
# -*- coding: utf-8 -*-
import scrapy, re
from laRazon.items import NoticiasItem
"""
MEDIO:
La Razón de México, CDMX
USO:
scrapy crawl noticias --nolog -s filename=2017-09-28.json -a year=2017 -a month=9 -a day=28
"""
TAG_RE = re.compile(r'<[^>]+>')
def remove_tags(text):
return TAG_RE.sub('', text)
class QuotesSpider(scrapy.Spider):
name = "noticias"
def start_requests(self):
year = getattr(self, 'year', None)
month = getattr(self, 'month', None)
day = getattr(self, 'day', None)
self.baseURL = "https://www.razon.com.mx/" + year + "/" + month + "/" + day
yield scrapy.Request(url=self.baseURL, callback=self.parse)
def parse(self, response):
yield scrapy.Request(url=response.url, callback=self.parse_page, dont_filter=True)
pagination = response.xpath('//*[@class="page-nav td-pb-padding-side"]/a/@href').extract()
if len(pagination) > 0:
pagination = pagination[-2].strip('/')
pages = int(pagination[pagination.rfind('/')+1:])
for page in range(1, pages):
yield scrapy.Request(url=self.baseURL+"/page/"+str(page+1), callback=self.parse_page)
def parse_page(self, response):
for link in response.xpath('//*[@class="td_module_1 td_module_wrap td-animation-stack"]/h3[@class="entry-title td-module-title"]/a/@href').extract():
yield scrapy.Request(url=link, callback=self.parse_item)
def parse_item(self, response):
item = NoticiasItem()
text = ''
d = response.xpath('//span[@class="td-post-date td-post-date-no-dot"]/time/@datetime').extract_first()
## '-06:00' corresponde al UTC-6, zona horaria del centro de mexico
if d[-6:] != '-06:00':
d = d[:-6] + '-06:00'
item['date'] = d
try:
topic = response.xpath('//*[@class="entry-crumbs"]/span/a[@class="entry-crumb"]/text()').extract()[2]
except:
try:
topic = response.xpath('//*[@class="entry-crumbs"]/span/a[@class="entry-crumb"]/text()').extract()[1]
except:
topic = response.xpath('//*[@class="entry-crumbs"]/span/a[@class="entry-crumb"]/text()').extract_first()
item['topic'] = topic
ti = response.xpath('//*[@class="td-post-header"]/header/h1/text()').extract_first()
if ti is None:
ti = response.xpath('//header[@class="td-post-title"]/h1/text()').extract_first()
item['title'] = ti
author = response.xpath('//div[@class="td-post-author-name"]/a/text()').extract_first()
if author is not None:
item['author'] = author
paragraphs = response.xpath('//*[@class="td-post-content"]/p').extract()
if len(paragraphs) <= 0:
paragraphs = response.xpath('//*[@dir="auto"]').extract()
for p in paragraphs:
text += remove_tags(p) + '\n'
item['text'] = text
item['url'] = response.url
# print item['title']
yield item
# Automatically created by: scrapy startproject
#
# For more information about the [deploy] section see:
# https://scrapyd.readthedocs.org/en/latest/deploy.html
[settings]
default = laRazon.settings
[deploy]
#url = http://localhost:6800/
project = laRazon
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class NoticiasItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
text = scrapy.Field()
date = scrapy.Field()
location = scrapy.Field()
author = scrapy.Field()
topic = scrapy.Field()
url = scrapy.Field()
# -*- coding: utf-8 -*-
# Define here the models for your spider middleware
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/spider-middleware.html
from scrapy import signals
class PorestoSpiderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the spider middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_spider_input(self, response, spider):
# Called for each response that goes through the spider
# middleware and into the spider.
# Should return None or raise an exception.
return None
def process_spider_output(self, response, result, spider):
# Called with the results returned from the Spider, after
# it has processed the response.
# Must return an iterable of Request, dict or Item objects.
for i in result:
yield i
def process_spider_exception(self, response, exception, spider):
# Called when a spider or process_spider_input() method
# (from other spider middleware) raises an exception.
# Should return either None or an iterable of Response, dict
# or Item objects.
pass
def process_start_requests(self, start_requests, spider):
# Called with the start requests of the spider, and works
# similarly to the process_spider_output() method, except
# that it doesn’t have a response associated.
# Must return only requests (not items).
for r in start_requests:
yield r
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
class PorestoDownloaderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the downloader middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_request(self, request, spider):
# Called for each request that goes through the downloader
# middleware.
# Must either:
# - return None: continue processing this request
# - or return a Response object
# - or return a Request object
# - or raise IgnoreRequest: process_exception() methods of
# installed downloader middleware will be called
return None
def process_response(self, request, response, spider):
# Called with the response returned from the downloader.
# Must either;
# - return a Response object
# - return a Request object
# - or raise IgnoreRequest
return response
def process_exception(self, request, exception, spider):
# Called when a download handler or a process_request()
# (from other downloader middleware) raises an exception.
# Must either:
# - return None: continue processing this exception
# - return a Response object: stops process_exception() chain
# - return a Request object: stops process_exception() chain
pass
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
import json
from collections import OrderedDict
class JsonWriterPipeline(object):
def __init__(self, filename):
self.filename = filename
@classmethod
def from_crawler(cls, crawler):
# Here you get whatever value was passed through the "filename" command line parameter
settings = crawler.settings
filename = settings.get('filename')
# Instantiate the pipeline with the file name
return cls(filename)
def open_spider(self, spider):
self.counter = 0
self.file = open(self.filename, 'w')
self.file.write("[")
def close_spider(self, spider):
self.file.write("]")
self.file.close()
def process_item(self, item, spider):
# print("this is my item", item)
row = []
try:
row.append(("date", item['date']))
except:
pass
try:
row.append(("topic", item['topic']))
except:
pass
try:
row.append(("title", item['title']))
except:
pass
try:
row.append(("author", item['author']))
except:
pass
try:
row.append(("location", item['location']))
except:
pass
try:
row.append(("text", item['text']))
except:
pass
try:
row.append(("url", item['url']))
except:
pass
line = OrderedDict(row)
self.counter += 1
if self.counter == 1:
self.file.write(json.dumps(line))
elif self.counter > 1:
self.file.write(",\n" + json.dumps(line))
return item
# -*- coding: utf-8 -*-
# Scrapy settings for porEsto project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
# https://doc.scrapy.org/en/latest/topics/settings.html
# https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
# https://doc.scrapy.org/en/latest/topics/spider-middleware.html
BOT_NAME = 'porEsto'
SPIDER_MODULES = ['porEsto.spiders']
NEWSPIDER_MODULE = 'porEsto.spiders'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'porEsto (+http://www.yourdomain.com)'
# Obey robots.txt rules
# ROBOTSTXT_OBEY = True
# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32
# Configure a delay for requests for the same website (default: 0)
# See https://doc.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.5
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16
# Disable cookies (enabled by default)
COOKIES_ENABLED = False
# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False
# Override the default request headers:
#DEFAULT_REQUEST_HEADERS = {
# 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
# 'Accept-Language': 'en',
#}
# Enable or disable spider middlewares
# See https://doc.scrapy.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
# 'porEsto.middlewares.PorestoSpiderMiddleware': 543,
#}
# Enable or disable downloader middlewares
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
# 'porEsto.middlewares.PorestoDownloaderMiddleware': 543,
#}
# Enable or disable extensions
# See https://doc.scrapy.org/en/latest/topics/extensions.html
#EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None,
#}
# Configure item pipelines
# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'porEsto.pipelines.JsonWriterPipeline': 300,
}
# Enable and configure the AutoThrottle extension (disabled by default)
# See https://doc.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True
# The initial download delay
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False
# Enable and configure HTTP caching (disabled by default)
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
# This package will contain the spiders of your Scrapy project
#
# Please refer to the documentation for information on how to create and manage
# your spiders.
# -*- coding: utf-8 -*-
"""
MEDIA:
Por Esto!, Yucatán
USAGE:
## Get all the news from a specific date. ##
---------------------------------------------------------------------------------------------
$ cd porEsto/
$ scrapy crawl noticias --nolog -s filename=2018-08-22.json -a year=2018 -a month=8 -a day=22
"""
import scrapy, re, json
from porEsto.items import NoticiasItem
from datetime import datetime, timedelta, tzinfo
TAG_RE = re.compile(r'<[^>]+>')
def remove_tags(text):
return TAG_RE.sub('', text)
class QuotesSpider(scrapy.Spider):
"""
Basic Scrapy Spider class
"""
name = "noticias"
def start_requests(self):
year = getattr(self, "year", None)
month = getattr(self, "month", None)
day = getattr(self, "day", None)
baseURL = "http://www.poresto.net/" + year + "/" + month.zfill(2) + "/" + day.zfill(2) + "/"
yield scrapy.Request(url=baseURL, callback=self.parse)
def parse(self, response):
for link in response.css('div.jeg_inner_content').css('h3.jeg_post_title > a::attr(href)').extract():
yield scrapy.Request(url=link, callback=self.parse_item)
next_page = response.css('div.jeg_navigation').css('a.next::attr(href)').extract_first()
if next_page is not None:
yield scrapy.Request(url=next_page, callback=self.parse)
def parse_item(self, response):
item = NoticiasItem()
text = ''
news_date = response.xpath('//meta[@property="article:published_time"]/@content').extract_first()
title = response.css('h1.jeg_post_title').extract_first()
if title is not None: title = remove_tags(title)
topic = response.css('div.jeg_meta_category > span > a').extract_first()
if topic is not None: topic = remove_tags(topic)
for p in response.css('div.entry-content').css('p').extract():
text += remove_tags(p) + "\n"
if text == '':
text = response.css('div.entry-content').css('div.content-inner').extract_first()
text.replace("<br>", '')
text = remove_tags(text)
## News item info ##
item['date'] = news_date
item['title'] = title
item['topic'] = topic
item['text'] = text.strip()
item['url'] = response.url
yield item
# Automatically created by: scrapy startproject
#
# For more information about the [deploy] section see:
# https://scrapyd.readthedocs.io/en/latest/deploy.html
[settings]
default = porEsto.settings
[deploy]
#url = http://localhost:6800/
project = porEsto
# -*- coding: utf-8 -*-
# Define here the models for your scraped items # Define here the models for your scraped items
# #
# See documentation in: # See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html # https://docs.scrapy.org/en/latest/topics/items.html
import scrapy import scrapy
class NoticiasItem(scrapy.Item): class PuntomedioItem(scrapy.Item):
# define the fields for your item here like: # define the fields for your item here like:
# name = scrapy.Field() # name = scrapy.Field()
date = scrapy.Field()
title = scrapy.Field() title = scrapy.Field()
text = scrapy.Field() text = scrapy.Field()
date = scrapy.Field()
location = scrapy.Field() location = scrapy.Field()
author = scrapy.Field() author = scrapy.Field()
topic = scrapy.Field() topic = scrapy.Field()
url = scrapy.Field() url = scrapy.Field()
# media = scrapy.Field()
# -*- coding: utf-8 -*-
# Define here the models for your spider middleware # Define here the models for your spider middleware
# #
# See documentation in: # See documentation in:
# http://doc.scrapy.org/en/latest/topics/spider-middleware.html # https://docs.scrapy.org/en/latest/topics/spider-middleware.html
from scrapy import signals from scrapy import signals
# useful for handling different item types with a single interface
from itemadapter import is_item, ItemAdapter
class PuntomedioSpiderMiddleware(object): class PuntomedioSpiderMiddleware:
# Not all methods need to be defined. If a method is not defined, # Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the spider middleware does not modify the # scrapy acts as if the spider middleware does not modify the
# passed objects. # passed objects.
...@@ -20,30 +21,29 @@ class PuntomedioSpiderMiddleware(object): ...@@ -20,30 +21,29 @@ class PuntomedioSpiderMiddleware(object):
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened) crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s return s
def process_spider_input(response, spider): def process_spider_input(self, response, spider):
# Called for each response that goes through the spider # Called for each response that goes through the spider
# middleware and into the spider. # middleware and into the spider.
# Should return None or raise an exception. # Should return None or raise an exception.
return None return None
def process_spider_output(response, result, spider): def process_spider_output(self, response, result, spider):
# Called with the results returned from the Spider, after # Called with the results returned from the Spider, after
# it has processed the response. # it has processed the response.
# Must return an iterable of Request, dict or Item objects. # Must return an iterable of Request, or item objects.
for i in result: for i in result:
yield i yield i
def process_spider_exception(response, exception, spider): def process_spider_exception(self, response, exception, spider):
# Called when a spider or process_spider_input() method # Called when a spider or process_spider_input() method
# (from other spider middleware) raises an exception. # (from other spider middleware) raises an exception.
# Should return either None or an iterable of Response, dict # Should return either None or an iterable of Request or item objects.
# or Item objects.
pass pass
def process_start_requests(start_requests, spider): def process_start_requests(self, start_requests, spider):
# Called with the start requests of the spider, and works # Called with the start requests of the spider, and works
# similarly to the process_spider_output() method, except # similarly to the process_spider_output() method, except
# that it doesn’t have a response associated. # that it doesn’t have a response associated.
...@@ -54,3 +54,50 @@ class PuntomedioSpiderMiddleware(object): ...@@ -54,3 +54,50 @@ class PuntomedioSpiderMiddleware(object):
def spider_opened(self, spider): def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name) spider.logger.info('Spider opened: %s' % spider.name)
class PuntomedioDownloaderMiddleware:
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the downloader middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_request(self, request, spider):
# Called for each request that goes through the downloader
# middleware.
# Must either:
# - return None: continue processing this request
# - or return a Response object
# - or return a Request object
# - or raise IgnoreRequest: process_exception() methods of
# installed downloader middleware will be called
return None
def process_response(self, request, response, spider):
# Called with the response returned from the downloader.
# Must either;
# - return a Response object
# - return a Request object
# - or raise IgnoreRequest
return response
def process_exception(self, request, exception, spider):
# Called when a download handler or a process_request()
# (from other downloader middleware) raises an exception.
# Must either:
# - return None: continue processing this exception
# - return a Response object: stops process_exception() chain
# - return a Request object: stops process_exception() chain
pass
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
# -*- coding: utf-8 -*-
# Define your item pipelines here # Define your item pipelines here
# #
# Don't forget to add your pipeline to the ITEM_PIPELINES setting # Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
import json
from collections import OrderedDict
class JsonWriterPipeline(object):
def __init__(self, filename):
self.filename = filename
@classmethod
def from_crawler(cls, crawler):
# Here you get whatever value was passed through the "filename" command line parameter
settings = crawler.settings
filename = settings.get('filename')
# Instantiate the pipeline with the file name # useful for handling different item types with a single interface
return cls(filename) from itemadapter import ItemAdapter
def open_spider(self, spider):
self.counter = 0
self.file = open(self.filename, 'w')
self.file.write("[")
def close_spider(self, spider):
self.file.write("]")
self.file.close()
class PuntomedioPipeline:
def process_item(self, item, spider): def process_item(self, item, spider):
# print("this is my item", item)
row = []
try:
row.append(("date", item['date']))
except:
pass
try:
row.append(("topic", item['topic']))
except:
pass
try:
row.append(("title", item['title']))
except:
pass
try:
row.append(("author", item['author']))
except:
pass
try:
row.append(("location", item['location']))
except:
pass
try:
row.append(("text", item['text']))
except:
pass
try:
row.append(("url", item['url']))
except:
pass
line = OrderedDict(row)
self.counter += 1
if self.counter == 1:
self.file.write(json.dumps(line))
elif self.counter > 1:
self.file.write(",\n" + json.dumps(line))
return item return item
# -*- coding: utf-8 -*-
# Scrapy settings for puntoMedio project # Scrapy settings for puntoMedio project
# #
# For simplicity, this file contains only settings considered important or # For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation: # commonly used. You can find more settings consulting the documentation:
# #
# http://doc.scrapy.org/en/latest/topics/settings.html # https://docs.scrapy.org/en/latest/topics/settings.html
# http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html # https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
# http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html # https://docs.scrapy.org/en/latest/topics/spider-middleware.html
BOT_NAME = 'puntoMedio' BOT_NAME = 'puntoMedio'
SPIDER_MODULES = ['puntoMedio.spiders'] SPIDER_MODULES = ['puntoMedio.spiders']
NEWSPIDER_MODULE = 'puntoMedio.spiders' NEWSPIDER_MODULE = 'puntoMedio.spiders'
FEED_EXPORT_ENCODING="utf-8"
# Crawl responsibly by identifying yourself (and your website) on the user-agent # Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'puntoMedio (+http://www.yourdomain.com)' #USER_AGENT = 'puntoMedio (+http://www.yourdomain.com)'
# Obey robots.txt rules # Obey robots.txt rules
# ROBOTSTXT_OBEY = True ROBOTSTXT_OBEY = True
# Configure maximum concurrent requests performed by Scrapy (default: 16) # Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32 #CONCURRENT_REQUESTS = 32
# Configure a delay for requests for the same website (default: 0) # Configure a delay for requests for the same website (default: 0)
# See http://scrapy.readthedocs.org/en/latest/topics/settings.html#download-delay # See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs # See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.5 #DOWNLOAD_DELAY = 3
# The download delay setting will honor only one of: # The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16 #CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16 #CONCURRENT_REQUESTS_PER_IP = 16
# Disable cookies (enabled by default) # Disable cookies (enabled by default)
COOKIES_ENABLED = False #COOKIES_ENABLED = False
# Disable Telnet Console (enabled by default) # Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False #TELNETCONSOLE_ENABLED = False
...@@ -45,31 +43,31 @@ COOKIES_ENABLED = False ...@@ -45,31 +43,31 @@ COOKIES_ENABLED = False
#} #}
# Enable or disable spider middlewares # Enable or disable spider middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html # See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = { #SPIDER_MIDDLEWARES = {
# 'puntoMedio.middlewares.PuntomedioSpiderMiddleware': 543, # 'puntoMedio.middlewares.PuntomedioSpiderMiddleware': 543,
#} #}
# Enable or disable downloader middlewares # Enable or disable downloader middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html # See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = { #DOWNLOADER_MIDDLEWARES = {
# 'puntoMedio.middlewares.MyCustomDownloaderMiddleware': 543, # 'puntoMedio.middlewares.PuntomedioDownloaderMiddleware': 543,
#} #}
# Enable or disable extensions # Enable or disable extensions
# See http://scrapy.readthedocs.org/en/latest/topics/extensions.html # See https://docs.scrapy.org/en/latest/topics/extensions.html
#EXTENSIONS = { #EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None, # 'scrapy.extensions.telnet.TelnetConsole': None,
#} #}
# Configure item pipelines # Configure item pipelines
# See http://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html # See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = { #ITEM_PIPELINES = {
'puntoMedio.pipelines.JsonWriterPipeline': 300, # 'puntoMedio.pipelines.PuntomedioPipeline': 300,
} #}
# Enable and configure the AutoThrottle extension (disabled by default) # Enable and configure the AutoThrottle extension (disabled by default)
# See http://doc.scrapy.org/en/latest/topics/autothrottle.html # See https://docs.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True #AUTOTHROTTLE_ENABLED = True
# The initial download delay # The initial download delay
#AUTOTHROTTLE_START_DELAY = 5 #AUTOTHROTTLE_START_DELAY = 5
...@@ -82,7 +80,7 @@ ITEM_PIPELINES = { ...@@ -82,7 +80,7 @@ ITEM_PIPELINES = {
#AUTOTHROTTLE_DEBUG = False #AUTOTHROTTLE_DEBUG = False
# Enable and configure HTTP caching (disabled by default) # Enable and configure HTTP caching (disabled by default)
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings # See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True #HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0 #HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache' #HTTPCACHE_DIR = 'httpcache'
......
# -*- coding: utf-8 -*- import scrapy
from puntoMedio.items import NoticiasItem from puntoMedio.items import PuntomedioItem
import scrapy, re import re
#-------------------------------------------------------------------------------
"""
MEDIO:
Punto Medio, Yucatán
USO:
scrapy crawl noticias --nolog -s filename=2018-09-28.json -a year=2017 -a month=9 -a day=28
"""
TAG_RE = re.compile(r'<[^>]+>') TAG_RE = re.compile(r'<[^>]+>')
def remove_tags(text): def remove_tags(text):
return TAG_RE.sub('', text) return TAG_RE.sub('', text)
#-------------------------------------------------------------------------------
class QuotesSpider(scrapy.Spider): class NoticiasSpider(scrapy.Spider):
name = "noticias" name = 'noticias'
allowed_domains = ['puntomedio.mx']
start_urls = ['http://puntomedio.mx/']
def start_requests(self): def start_requests(self):
year = getattr(self, 'year', None) year = getattr(self, 'year', None)
...@@ -24,36 +19,25 @@ class QuotesSpider(scrapy.Spider): ...@@ -24,36 +19,25 @@ class QuotesSpider(scrapy.Spider):
self.baseURL = "http://www.puntomedio.mx/" + year + "/" + month + "/" + day self.baseURL = "http://www.puntomedio.mx/" + year + "/" + month + "/" + day
yield scrapy.Request(url=self.baseURL, callback=self.parse) yield scrapy.Request(url=self.baseURL, callback=self.parseDate)
#-----------------------------------------------------------------------
def parseDate(self, response):
def parse(self, response):
for link in response.css('div.col-md-8').css('h2.title').css('a::attr(href)').extract(): for link in response.css('div.col-md-8').css('h2.title').css('a::attr(href)').extract():
yield scrapy.Request(url=link, callback=self.parse_item) yield scrapy.Request(url=link, callback=self.parse_item)
nextPage = response.css('div.pagination').css('a.older-posts::attr(href)').extract_first() nextPage = response.css('div.pagination').css('a.older-posts::attr(href)').extract_first()
yield scrapy.Request(url=nextPage, callback=self.parse) print("nextPage", nextPage)
if nextPage is not None:
yield scrapy.Request(url=nextPage, callback=self.parseDate)
def parse_item(self, response): def parse_item(self, response):
item = NoticiasItem() item = PuntomedioItem()
text = '' text = ''
item["date"] = response.xpath('//meta[@property="article:published_time"]/@content').extract_first()
item['title'] = response.css('h1.title::text').extract_first() item['title'] = response.css('h1.title::text').extract_first()
d = response.xpath('//meta[@property="article:published_time"]/@content').extract_first()
## '-06:00' corresponde al UTC-6, zona horaria de yucatan (centro de mexico)
if d[-6:] != '-06:00':
d = d[:-6] + '-06:00'
item['date'] = d
item['topic'] = response.xpath('//ul[@class="post-categories"]/li/a/text()').extract_first() item['topic'] = response.xpath('//ul[@class="post-categories"]/li/a/text()').extract_first()
for p in response.css('div.post-entry').css('p').extract(): for p in response.css('div.post-entry').css('p').extract():
text += remove_tags(p) text += remove_tags(p)
item['text'] = text item['text'] = text
item['url'] = response.url item['url'] = response.url
print(item["title"])
# print item['title']
yield item yield item
# Automatically created by: scrapy startproject # Automatically created by: scrapy startproject
# #
# For more information about the [deploy] section see: # For more information about the [deploy] section see:
# https://scrapyd.readthedocs.org/en/latest/deploy.html # https://scrapyd.readthedocs.io/en/latest/deploy.html
[settings] [settings]
default = puntoMedio.settings default = puntoMedio.settings
......
# Automatically created by: scrapy startproject
#
# For more information about the [deploy] section see:
# https://scrapyd.readthedocs.org/en/latest/deploy.html
[settings]
default = sintesis.settings
[deploy]
#url = http://localhost:6800/
project = sintesis
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class NoticiasItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
text = scrapy.Field()
date = scrapy.Field()
location = scrapy.Field()
author = scrapy.Field()
topic = scrapy.Field()
url = scrapy.Field()
# -*- coding: utf-8 -*-
# Define here the models for your spider middleware
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/spider-middleware.html
from scrapy import signals
class SintesisSpiderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the spider middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_spider_input(response, spider):
# Called for each response that goes through the spider
# middleware and into the spider.
# Should return None or raise an exception.
return None
def process_spider_output(response, result, spider):
# Called with the results returned from the Spider, after
# it has processed the response.
# Must return an iterable of Request, dict or Item objects.
for i in result:
yield i
def process_spider_exception(response, exception, spider):
# Called when a spider or process_spider_input() method
# (from other spider middleware) raises an exception.
# Should return either None or an iterable of Response, dict
# or Item objects.
pass
def process_start_requests(start_requests, spider):
# Called with the start requests of the spider, and works
# similarly to the process_spider_output() method, except
# that it doesn’t have a response associated.
# Must return only requests (not items).
for r in start_requests:
yield r
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
import json
from collections import OrderedDict
class JsonWriterPipeline(object):
def __init__(self, filename):
self.filename = filename
@classmethod
def from_crawler(cls, crawler):
# Here you get whatever value was passed through the "filename" command line parameter
settings = crawler.settings
filename = settings.get('filename')
# Instantiate the pipeline with the file name
return cls(filename)
def open_spider(self, spider):
self.counter = 0
self.file = open(self.filename, 'w')
self.file.write("[")
def close_spider(self, spider):
self.file.write("]")
self.file.close()
def process_item(self, item, spider):
# print("this is my item", item)
row = []
try:
row.append(("date", item['date']))
except:
pass
try:
row.append(("topic", item['topic']))
except:
pass
try:
row.append(("title", item['title']))
except:
pass
try:
row.append(("author", item['author']))
except:
pass
try:
row.append(("location", item['location']))
except:
pass
try:
row.append(("text", item['text']))
except:
pass
try:
row.append(("url", item['url']))
except:
pass
line = OrderedDict(row)
self.counter += 1
if self.counter == 1:
self.file.write(json.dumps(line))
elif self.counter > 1:
self.file.write(",\n" + json.dumps(line))
return item
# -*- coding: utf-8 -*-
# Scrapy settings for sintesis project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
# http://doc.scrapy.org/en/latest/topics/settings.html
# http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
# http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html
BOT_NAME = 'sintesis'
SPIDER_MODULES = ['sintesis.spiders']
NEWSPIDER_MODULE = 'sintesis.spiders'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'sintesis (+http://www.yourdomain.com)'
# Obey robots.txt rules
# ROBOTSTXT_OBEY = True
# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32
# Configure a delay for requests for the same website (default: 0)
# See http://scrapy.readthedocs.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.5
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16
# Disable cookies (enabled by default)
COOKIES_ENABLED = False
# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False
# Override the default request headers:
#DEFAULT_REQUEST_HEADERS = {
# 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
# 'Accept-Language': 'en',
#}
# Enable or disable spider middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
# 'sintesis.middlewares.SintesisSpiderMiddleware': 543,
#}
# Enable or disable downloader middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
# 'sintesis.middlewares.MyCustomDownloaderMiddleware': 543,
#}
# Enable or disable extensions
# See http://scrapy.readthedocs.org/en/latest/topics/extensions.html
#EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None,
#}
# Configure item pipelines
# See http://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'sintesis.pipelines.JsonWriterPipeline': 300,
}
# Enable and configure the AutoThrottle extension (disabled by default)
# See http://doc.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True
# The initial download delay
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False
# Enable and configure HTTP caching (disabled by default)
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
# This package will contain the spiders of your Scrapy project
#
# Please refer to the documentation for information on how to create and manage
# your spiders.
# -*- coding: utf-8 -*-
import scrapy, re
from sintesis.items import NoticiasItem
"""
MEDIO:
Síntesis, Puebla
USO:
scrapy crawl noticias --nolog -s filename=2018-02-04.json -a year=2018 -a month=2 -a day=4
"""
TAG_RE = re.compile(r'<[^>]+>')
def remove_tags(text):
return TAG_RE.sub('', text)
# LOC_RE = re.compile(r'\n.+?,? ?.+? ?\. ?- ?')
# G_RE = re.compile(r' ?- ?')
# EM_RE = re.compile(r'((Email|Correo electr.{1,3}nico|Comentarios?):\s)?[\w.-]+@[\w-]+(\.[a-zA-Z]{2,6}){1,2}\s?')
# TW_RE = re.compile(r'M.{1,3}s de la P.{1,3}lvora en Twitter: @[\w.%+-]+.', re.I)
# TW2_RE = re.compile(r'((\| )?Twitter:\s+)?(@[\w.%+-]+.)?', re.I)
# TAG2_RE = re.compile(r'\ntransition_[^\]]+\]')
# TAG3_RE = re.compile(r'\[[^\]]+[\]\n]')
class QuotesSpider(scrapy.Spider):
name = "noticias"
def start_requests(self):
year = getattr(self, "year", None)
month = getattr(self, "month", None)
day = getattr(self, "day", None)
self.baseURL = "https://www.sintesis.mx/" + year + "/" + month.zfill(2) + "/" + day.zfill(2)
yield scrapy.Request(url=self.baseURL, callback=self.parse)
def parse(self, response):
yield scrapy.Request(url=response.url, callback=self.parse_page, dont_filter=True)
pagination = response.css('div.page-nav').xpath('./a/@href').extract()
if len(pagination) > 0:
pagination = pagination[-2].strip('/')
pages = int(pagination[pagination.rfind('/') + 1:])
for page in range(1, pages):
yield scrapy.Request(url=self.baseURL + '/page/' + str(page + 1), callback=self.parse_page)
def parse_page(self, response):
for link in response.xpath('//div[@class="td-ss-main-content"]').css('h3.entry-title').xpath('./a/@href').extract():
yield scrapy.Request(url=link, callback=self.parse_item)
def parse_item(self, response):
item = NoticiasItem()
text = ''
"La fecha obtenida ya incluye formato y zona horaria"
item['date'] = response.xpath('//span[@class="td-post-date"]/time/@datetime').extract_first()
item['title'] = remove_tags(response.xpath('//header[@class="td-post-title"]/h1').extract_first()).strip()
topic = response.xpath('//ul[@class="td-category"]/li/a').extract_first()
if topic is not None:
item['topic'] = remove_tags(topic)
author = response.xpath('//div[@class="td-post-author-name"]/a').extract_first()
if author is not None:
item['author'] = remove_tags(author)
for p in response.xpath('//div[@class="td-post-content"]').css('p').extract():
text += remove_tags(p) + "\n"
# result = LOC_RE.search(text)
# if result:
# m = result.group(0)
# location = G_RE.sub('', m).strip()
# if len(location) <= 35:
# item['location'] = location
# text = text[text.find(m)+len(m):]
# text = EM_RE.sub('', text)
# text = TW_RE.sub('', text)
# text = TW2_RE.sub('', text)
# text = TAG2_RE.sub("\n", text)
# text = TAG3_RE.sub('', text)
item['text'] = text.strip()
item['url'] = response.url
yield item
# Automatically created by: scrapy startproject
#
# For more information about the [deploy] section see:
# https://scrapyd.readthedocs.org/en/latest/deploy.html
[settings]
default = unoMasUno.settings
[deploy]
#url = http://localhost:6800/
project = unoMasUno
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class NoticiasItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
text = scrapy.Field()
date = scrapy.Field()
location = scrapy.Field()
author = scrapy.Field()
topic = scrapy.Field()
url = scrapy.Field()
# -*- coding: utf-8 -*-
# Define here the models for your spider middleware
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/spider-middleware.html
from scrapy import signals
class UnomasunoSpiderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the spider middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_spider_input(response, spider):
# Called for each response that goes through the spider
# middleware and into the spider.
# Should return None or raise an exception.
return None
def process_spider_output(response, result, spider):
# Called with the results returned from the Spider, after
# it has processed the response.
# Must return an iterable of Request, dict or Item objects.
for i in result:
yield i
def process_spider_exception(response, exception, spider):
# Called when a spider or process_spider_input() method
# (from other spider middleware) raises an exception.
# Should return either None or an iterable of Response, dict
# or Item objects.
pass
def process_start_requests(start_requests, spider):
# Called with the start requests of the spider, and works
# similarly to the process_spider_output() method, except
# that it doesn’t have a response associated.
# Must return only requests (not items).
for r in start_requests:
yield r
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
import json
from collections import OrderedDict
class JsonWriterPipeline(object):
def __init__(self, filename):
self.filename = filename
@classmethod
def from_crawler(cls, crawler):
# Here you get whatever value was passed through the "filename" command line parameter
settings = crawler.settings
filename = settings.get('filename')
# Instantiate the pipeline with the file name
return cls(filename)
def open_spider(self, spider):
self.counter = 0
self.file = open(self.filename, 'w')
self.file.write("[")
def close_spider(self, spider):
self.file.write("]")
self.file.close()
def process_item(self, item, spider):
# print("this is my item", item)
row = []
try:
row.append(("date", item['date']))
except:
pass
try:
row.append(("topic", item['topic']))
except:
pass
try:
row.append(("title", item['title']))
except:
pass
try:
row.append(("author", item['author']))
except:
pass
try:
row.append(("location", item['location']))
except:
pass
try:
row.append(("text", item['text']))
except:
pass
try:
row.append(("url", item['url']))
except:
pass
line = OrderedDict(row)
self.counter += 1
if self.counter == 1:
self.file.write(json.dumps(line))
elif self.counter > 1:
self.file.write(",\n" + json.dumps(line))
return item
# -*- coding: utf-8 -*-
# Scrapy settings for unoMasUno project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
# http://doc.scrapy.org/en/latest/topics/settings.html
# http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
# http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html
BOT_NAME = 'unoMasUno'
SPIDER_MODULES = ['unoMasUno.spiders']
NEWSPIDER_MODULE = 'unoMasUno.spiders'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'unoMasUno (+http://www.yourdomain.com)'
# Obey robots.txt rules
# ROBOTSTXT_OBEY = True
# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32
# Configure a delay for requests for the same website (default: 0)
# See http://scrapy.readthedocs.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.5
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16
# Disable cookies (enabled by default)
COOKIES_ENABLED = False
# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False
# Override the default request headers:
#DEFAULT_REQUEST_HEADERS = {
# 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
# 'Accept-Language': 'en',
#}
# Enable or disable spider middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
# 'unoMasUno.middlewares.UnomasunoSpiderMiddleware': 543,
#}
# Enable or disable downloader middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
# 'unoMasUno.middlewares.MyCustomDownloaderMiddleware': 543,
#}
# Enable or disable extensions
# See http://scrapy.readthedocs.org/en/latest/topics/extensions.html
#EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None,
#}
# Configure item pipelines
# See http://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'unoMasUno.pipelines.JsonWriterPipeline': 300,
}
# Enable and configure the AutoThrottle extension (disabled by default)
# See http://doc.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True
# The initial download delay
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False
# Enable and configure HTTP caching (disabled by default)
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
# This package will contain the spiders of your Scrapy project
#
# Please refer to the documentation for information on how to create and manage
# your spiders.
# -*- coding: utf-8 -*-
import scrapy, re, json
from unoMasUno.items import NoticiasItem
from datetime import datetime, timedelta, tzinfo
"""
MEDIO:
Uno Más Uno, Yucatán
USO:
scrapy crawl noticias --nolog -s filename=2017-09-22.json -a year=2017 -a month=9 -a day=22
"""
TAG_RE = re.compile(r'<[^>]+>')
def remove_tags(text):
return TAG_RE.sub('', text)
class UTC(tzinfo):
"""clase para el 'time zone' (zona horaria)"""
def utcoffset(self, dt):
# zona horaria para hidalgo (centro de mexico): utc-6
return timedelta(hours=-6)
def tzname(self, dt):
# nombre de la zona horaria
return 'UTC-6'
class QuotesSpider(scrapy.Spider):
name = "noticias"
def start_requests(self):
self.tz = UTC()
self.year = getattr(self, 'year', None)
self.month = getattr(self, 'month', None)
self.day = getattr(self, 'day', None)
self.date_parser = {'enero': 1, 'febrero': 2, 'marzo': 3, 'abril': 4,
'mayo': 5, 'junio': 6, 'julio': 7, 'agosto': 8,
'septiembre': 9, 'octubre': 10, 'noviembre': 11, 'diciembre': 12}
self.baseURL = "http://www.unomasuno.com.mx/" + self.year + "/" + self.month + "/" + self.day
yield scrapy.Request(url=self.baseURL, callback=self.parse)
def parse(self, response):
yield scrapy.Request(url=response.url, callback=self.parse_page, dont_filter=True)
pagination = response.xpath('//*[@class="pagination"]/a[@class="last"]/@href').extract_first()
if pagination is None:
pagination = response.xpath('//*[@class="pagination"]/a/@href').extract()
if len(pagination) > 0:
pagination = pagination[-1].strip('/')
pages = int(pagination[pagination.rfind('/')+1:])
for page in range(1, pages):
yield scrapy.Request(url=self.baseURL+"/page/"+str(page+1), callback=self.parse_page)
else:
pagination = pagination.strip('/')
pages = int(pagination[pagination.rfind('/')+1:])
for page in range(1, pages):
yield scrapy.Request(url=self.baseURL+"/page/"+str(page+1), callback=self.parse_page)
def parse_page(self, response):
for link in response.xpath('//h2[@class="post-box-title"]/a/@href').extract():
yield scrapy.Request(url=link, callback=self.parse_item)
def parse_item(self, response):
item = NoticiasItem()
text = ''
try:
jsonInfo = response.xpath('//script[@type="application/ld+json"]').extract_first()
jsonInfo = json.loads(remove_tags(jsonInfo))
dat = jsonInfo['datePublished']
except:
try:
d = response.xpath('//p[@class="post-meta"]/span/text()').extract_first()
d = d.replace(',', '').split(' ')
dat = datetime(int(d[2]), self.date_parser[d[1].lower()], int(d[0]), tzinfo=self.tz).isoformat("T")
except:
dat = datetime(int(self.year), int(self.month), int(self.day), tzinfo=self.tz).isoformat("T")
item['date'] = dat
item['topic'] = response.xpath('//span[@typeof="v:Breadcrumb"]/a/text()').extract()[1]
item['title'] = response.xpath('//*[@class="post-inner"]/h1/span/text()').extract_first()
for p in response.xpath('//*[@class="entry"]/p').extract():
text += remove_tags(p) + '\n'
item['text'] = text
item['url'] = response.url
# print item['title']
yield item
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment