How do you find multiple, identical strings and list them?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • aikoiha
    New Member
    • Jun 2010
    • 2

    #1

    How do you find multiple, identical strings and list them?

    I'm extremely new, so bear with me.

    I have a webpage in xml displaying Earthquake information (Magnitude, place and etc.). I need to list each place and magnitude, which is located between <title> tags. The str.find() only works for one thing, but I need to list them all. Also, the page has an irrelevant title in the beginning and I need to start my search after that. This is what I have:

    Code:
    import urllib.request
    
    def printEarthquakeTitle(requestedURL):
        page = urllib.request.urlopen(requestedURL)
        text = page.read().decode("utf8")
        start = text.find("<title>") + 7
        end = text.find("</title")
        title = str(text[start:end])
        return title
    
    title = printEarthquakeTitle("http://earthquake.usgs.gov/eqcenter/catalogs/7day-M2.5.xml")
    print(title)
    This only prints out that first irrelevant title between the title tags. I need to print the one after that.

    And then I need to list all the titles after that one.

    I know I need a while/loop, but I don't know how to skip the first irrelevant title.

    This is basically the website:

    <title>irreleva nt title</title>

    <title>this is the title i need</title>

    <title>then I need to list these</title>
    <title>then I need to list these</title>
    <title>then I need to list these</title>
    <title>then I need to list these</title>

    I hope this makes sense.
  • bvdet
    Recognized Expert Specialist
    • Oct 2006
    • 2851

    #2
    You can advance through the text using find() by supplying a starting index as in:
    Code:
    >>> s = "12345678901234567xxx890"
    >>> i = s.find('7')
    >>> i
    6
    >>> s[s.find('7', i+1):]
    '7xxx890'
    >>>
    Ideally you would parse the XML with an XML parser such as xml.dom.minidom . Sample code:
    Code:
    from xml.dom import minidom
    
    xmlStr = '''<?xml version="1.0" ?>
    <data>
        <title>irrelevant title</title>
        <title>this is the title i need</title>
        <title>then I need to list these</title>
        <title>then I need to list these</title>
        <title>then I need to list these</title>
        <title>then I need to list these</title>
    </data>'''
    
    def getTextFromElem(parents):
        '''Return a list of text found in the child nodes of a list
        of parent nodes, discarding whitespace.'''
        textList = []
        for parent in parents:
            for n in parent.childNodes:
                # TEXT_NODE - 3
                if n.nodeType == 3 and n.nodeValue.strip():
                    textList.append(str(n.nodeValue.strip()))
        return textList
    
    docXML = minidom.parseString(xmlStr)
    nodeList = docXML.getElementsByTagName("title")
    textList = getTextFromElem(nodeList)
    for s in textList:
        print s
    Output:
    Code:
    >>> irrelevant title
    this is the title i need
    then I need to list these
    then I need to list these
    then I need to list these
    then I need to list these
    To exclude the first item:
    Code:
    textList[1:]
    Sample code using find():
    Code:
    def idx_list(seq, item):
        idxList = []
        idx = -1
        while True:
            idx = seq.find(item, idx+1)
            if idx == -1:
                break
            else:
                idxList.append(idx)
        return idxList
    
    def getTextFromDoc(doc, tag):
        startXs = idx_list(doc, "<%s>" % tag)
        endXs = idx_list(doc, "</%s>" % tag)
        try:
            assert len(startXs) == len(endXs)
        except AssertionError:
            print "Unbalanced tags"
            return []
        return [doc[i+len("<%s>" % tag):j] for i, j in zip(startXs, endXs)]
    
    print getTextFromDoc(xmlStr, 'title')

    Comment

    • aikoiha
      New Member
      • Jun 2010
      • 2

      #3
      Thanks!

      It took a bit going through it all, but with your help, I figured it out. Thanks!

      Comment

      Working...