Discover random web servers and print the index page title Github repo

I wrote this little toy today that probes random web servers and prints out the title of their index page. I'm curious if this code is any good since I'm a bit rusty.

get_titles.py

#!/usr/bin/env python

""" Probe random web server and print out the title of their index page. """

import os
import sys
import lxml.html


def get_title(url):
    '''Extract the title from a webpage.
    If anything goes wrong like the request
    times out or the page does not have a
    title get_title will return None'''
    try:
        title = lxml.html.parse(url)
        return title.find(".//title").text
    except KeyboardInterrupt:
        sys.exit(0)
    except Exception:
        return None

def shell(command):
    """Run a shell command.
    return it's output as a string"""
    return os.popen(command).read()

def scan(nhosts):
    """Run an nmap scan of n hosts.
    This will return IPv4 addresses of hosts
    that are up and have a service running on
    port 80. Simply supply the number of hosts
    you would like to check."""
    results = set(shell('./discover.sh {}'.format(nhosts)).split('\n'))
    if not results:
        print 'Nothing Found.'
        sys.exit(0)
    return ["http://{}".format(ip) for ip in results if ip]

def main():
    """ Run the scan."""
    if not len(sys.argv) &gt;= 2:
        print 'You forgot to tell me how many hosts to check'
        sys.exit(0)
    for url in scan(sys.argv[1]):
        title = get_title(url)
        if title:
            print title, url


if __name__ == '__main__':
    main()


discover.sh

#!/bin/bash

nhosts=$1

nmap \
--host-timeout 10s \
--max-retries 0 \
–min-parallelism 100 \
-T5 \
-Pn \
-n \
-iR $1 \
-p80 \
-oG tmp.txt \
--open \
tmp.txt &gt; /dev/null

cat tmp.txt | grep 'Host' | awk '{print $2}'
rm tmp.txt
Overall, the code is pretty clean. Some notes about the Python part:


be consistent about the documentation string style - enclose them with triple quotes, start with an upper-case letter, end with a dot (PEP8 reference). I also think that you can use less newline breaks there.
if we would follow PEP8 importing recommendations, there should be a newline between the "system" level imports and third-parties:

import os
import sys

import lxml.html

you should have 2 line breaks between the function definitions (reference)
use print() as a function for Python 3 compatibility
I would avoid unnecessary invert of the logic and replace:

if not len(sys.argv) &gt;= 2:


with:

if len(sys.argv) &lt; 2:

avoid using bare except clauses
you can use .findtext() method:

title.findtext(".//title")


which will return None if title element was not found.