Advertisement
Guest User

UCrawler

a guest
May 23rd, 2015
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.61 KB | None | 0 0
  1. import sys
  2. import mechanize
  3. from re import findall
  4.  
  5. class UCrawler(object):
  6.     def __init__(self, url=None, fname=None, debug=False):
  7.         self.__url = url
  8.         self.__file = fname
  9.         self.__debug = debug        
  10.         self.__links = []
  11.         self.__pages = []
  12.  
  13.     def run(self):
  14.         try:
  15.             if self.__url != None:
  16.                 self._crawl()
  17.  
  18.             elif self.__file != None:
  19.                 urls = self._getURLs()
  20.  
  21.                 for url in urls:
  22.                     if not url.startswith('https://'):
  23.                         continue
  24.  
  25.                     self.__url = url.split()[0]
  26.                     print self.__url
  27.                     self._crawl()
  28.  
  29.         except KeyboardInterrupt:
  30.             sys.exit(' [!] KeyboardInterrupt')
  31.  
  32.     def _getURLs(self):
  33.         try:
  34.             with open(self.__file, 'r') as f:
  35.                 urls = f.readlines()
  36.                 return urls
  37.  
  38.         except Exception as e:
  39.             self._showError(e)
  40.  
  41.     def _crawl(self):
  42.         if self.__url.endswith("/"):
  43.             self.__url = self.__url[:-1]
  44.  
  45.         try:
  46.             print '\n [*] Crawling {}'.format(self.__url)
  47.  
  48.             self._getPages()
  49.  
  50.             for page in self.__pages:
  51.                 links = self._getLinks(page)
  52.  
  53.                 for link in links:
  54.                    
  55.                     regex = '(%s\/\?.+|/\d{1,5}/)' % self.__url
  56.                     if findall(regex, link.url):
  57.                         with open("ignored_links.log", "a") as f:
  58.                             f.write(link.url + "\n")
  59.                         continue
  60.                    
  61.                     url = link.url.split('?PHPSESSID')[0]
  62.                     if url not in self.__links:
  63.                         if self.__debug:
  64.                             #print ' [TITLE] {}: {}'.format(link.text, url)
  65.                             pass
  66.  
  67.                         self.__links.append(url)
  68.  
  69.             print '\n [+] Links: {}'.format(len(self.__links))
  70.             self._save()
  71.             self._clean()
  72.  
  73.         except Exception as e:
  74.             self._showError(e)
  75.  
  76.     def _clean(self):
  77.         self.__links = []
  78.         self.__pages = []
  79.  
  80.     def _getLinks(self, url=None):
  81.         if url:            
  82.             print "\n [*] Getting links from {}".format(url)
  83.         else:
  84.             url = self.__url
  85.  
  86.         try:
  87.             br = mechanize.Browser()
  88.             br.open(url)
  89.  
  90.             if findall('\/\d.+', url):
  91.                 url = url.rsplit('/', 1)[0]
  92.  
  93.             return br.links(url_regex=url)
  94.  
  95.         except Exception as e:
  96.             self._showError(e)
  97.  
  98.     def _getPages(self):
  99.         try:
  100.             pages = []
  101.             links = self._getLinks()
  102.  
  103.             for link in links:
  104.                 if findall('^\d{1,5}$', link.text):
  105.                     num = int(link.text)
  106.  
  107.                     if num not in pages:
  108.                         pages.append(num)
  109.            
  110.             pages.sort()
  111.  
  112.             if len(pages) == 0:
  113.                 self.__pages.append(self.__url)
  114.                 return
  115.  
  116.             for i in range(pages[-1]):
  117.                 num = i * 40
  118.                
  119.                 if num == 0:
  120.                     page = self.__url
  121.                 else:
  122.                     page = "{}/{}".format(self.__url, num)
  123.                
  124.                 self.__pages.append(page)
  125.  
  126.             if self.__debug:
  127.                 print " [*] Pages:"
  128.                 for page in self.__pages:
  129.                     print "\t-", page
  130.  
  131.         except Exception as e:
  132.             self._showError(e)
  133.  
  134.     def _save(self):
  135.         xmlname = self._getXMLName()
  136.         print ' [*] Creating XML file [{}]'.format(xmlname)
  137.  
  138.         header = """<?xml version="1.0" encoding="UTF-8"?>
  139.            <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
  140.            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  141.            xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
  142.            http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">"""
  143.  
  144.         content = """
  145.            <url>
  146.                <loc>{}</loc>
  147.                <priority>0.5</priority>
  148.                <changefreq>daily</changefreq>
  149.                <lastmod>2015-05-20T21:48:08+00:00</lastmod>  
  150.            </url>"""
  151.        
  152.         footer = "</urlset>"
  153.  
  154.         try:
  155.             with open(xmlname, "w") as f:
  156.                 f.write(header)
  157.  
  158.                 for link in self.__links:
  159.                     f.write(content.format(link))
  160.  
  161.                 f.write(footer)
  162.  
  163.         except Exception as e:
  164.             self._showError(e)
  165.  
  166.     def _getXMLName(self):
  167.         xmlname = self.__url.rsplit('/', 1)[1] + '.xml'
  168.         return xmlname
  169.  
  170.     def _showError(self, e):
  171.         caller = sys._getframe().f_back.f_code.co_name
  172.  
  173.         if self.__debug:
  174.             print ' [!] Error: {0} (function: {1})'.format(e, caller)
  175.        
  176.         with open("error.log", "a") as f:
  177.             f.write("URL: {}\n".format(self.__url))
  178.             f.write("ERROR: {}\n".format(e))
  179.             f.write("METHOD: {}\n".format(caller))
  180.             f.write("--"*40 + "\n")
  181.  
  182.         self._exit()
  183.  
  184.     def _exit(self):
  185.         sys.exit()
  186.  
  187. USAGE = '''
  188. Usage: python {} [options]
  189.  
  190. Help Options:
  191.  -h, --help                Show help options
  192.  
  193. Debug Options:
  194.  --debug                   Debug mode
  195.  
  196. Application Options:
  197.  -u, --url=URL             Set the URL to crawl
  198.  -f, --file=FILE           Set the file containing the URLs to crawl
  199. '''.format(sys.argv[0])
  200.  
  201. def usage():
  202.     sys.exit(USAGE)
  203.  
  204. def parse():
  205.     args = sys.argv
  206.  
  207.     options = {
  208.         'url' : None,
  209.         'fname' : None,
  210.         'debug' : False,
  211.     }
  212.  
  213.     if '--debug' in args:
  214.         options['debug'] = True
  215.         args.pop(args.index('--debug'))
  216.  
  217.     if any((x in args for x in ['-h', '--help'])) or not (2 <= len(args) <= 3):
  218.         usage()
  219.  
  220.     if len(args) == 2:
  221.         if args[1].startswith('--url='):
  222.             options['url'] = args[1].split('=', 1)[1]
  223.         elif args[1].startswith('--file='):
  224.             options['fname'] = args[1].split('=', 1)[1]
  225.         else:
  226.             usage()
  227.  
  228.     if len(args) == 3:
  229.         if '-u' == args[1]:
  230.             options['url'] = args[2]
  231.         elif '-f' == args[1]:
  232.             options['fname'] = args[2]
  233.         else:
  234.             usage()
  235.  
  236.     return options.get('url'), options.get('fname'), options.get('debug')
  237.  
  238.  
  239. def main():
  240.     url, fname, debug = parse()
  241.  
  242.     uc = UCrawler(url=url, fname=fname, debug=debug)
  243.     uc.run()
  244.  
  245. if __name__ == '__main__':
  246.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement