Reputation: 59
I am currently trying to screen scrape a website to put info into a dictionary. I am using urllib2 and BeautifulSoup. I cannot figure out how to parse the web pages source info to get what I want and to read it into a dictionary. The info I want is displayed as <title>Nov 24 | 8:00AM | Sole In. Peace Out. </title>
in the source code. I am thinking of using a reg expression to read in the line, convert the time and date to a datetime, and then parse the line to read the data into a dictionary. The dictionary output should be something along the lines of
[
{
"date": dateime(2010, 11, 24, 23, 59),
"title": "Sole In. Peace Out.",
}
]
Current Code:
from BeautifulSoup import BeautifulSoup
import re
import urllib2
url = 'http://events.cmich.edu/RssStudentEvents.aspx'
response = urllib2.urlopen(url)
html = response.read()
soup = BeautifulSoup(html)
Sorry for the wall of text, and thank you for your time and help!
Upvotes: 0
Views: 626
Reputation: 612
Something like this..
titletext = soup.findAll('title')[1].string #assuming it's the second title element.. I've seen worse in html
import datetime
datetext = titletext.split("|")[0]
title = titletext.split("|")[2]
date = datetime.datetime.strptime(datetext,"%b %d").replace(year=2010)
the_final_dict = {'date':date,'title':title}
findAll()
returns all instances of the search element.. so you can just treat it like any other list.
That should just about do it :)
Edit: small fix
Edit2: fix from comments below
Upvotes: 1
Reputation: 90852
>>> soup.findAll('item')[1].title
<title>Nov 24 | 8:00AM | Sole In. Peace Out. </title>
>>> soup.findAll('item')[1].title.text
u'Nov 24 | 8:00AM | Sole In. Peace Out.'
>>> date, _, title = soup.findAll('item')[1].title.text.rpartition(' | ')
>>> date
u'Nov 24 | 8:00AM'
>>> title
u'Sole In. Peace Out.'
>>> from datetime import datetime
>>> date = datetime.strptime(date, "%b %d | %I:%M%p").replace(year=datetime.now().year)
>>> dict(date=date, title=title)
{'date': datetime.datetime(2010, 11, 24, 8, 0), 'title': u'Sole In. Peace Out.'}
Note that that's also including the time of day.
And then, as I think you want all the items,
>>> from datetime import datetime
>>> matches = []
>>> for item in soup.findAll('item'):
... date, _, title = item.title.text.rpartition(' | ')
... matches.append(dict(date=datetime.strptime(date, '%b %d | %I:%M%p').replace(year=datetime.now().year), title=title))
...
>>> from pprint import pprint
>>> pprint(matches)
[{'date': datetime.datetime(2010, 11, 24, 8, 0),
'title': u'The Americana Indian\u2014American Indian in the American Imagination'},
{'date': datetime.datetime(2010, 11, 24, 8, 0),
'title': u'Sole In. Peace Out.'},
...
{'date': datetime.datetime(2010, 12, 8, 8, 0),
'title': u'Apply to be an FYE Mentor'}]
If you wanted more complex year handling you could do it. You get the idea.
Final addition: a generator would be a nice way of using this.
from datetime import datetime
import urllib2
from BeautifulSoup import BeautifulSoup
def whatevers():
soup = BeautifulSoup(urllib2.urlopen('http://events.cmich.edu/RssStudentEvents.aspx').read())
for item in soup.findAll('item'):
date, _, title = item.title.text.rpartition(' | ')
yield dict(date=datetime.strptime(date, '%b %d | %I:%M%p').replace(year=datetime.now().year), title=title)
for match in whatevers():
pass # Use match['date'], match['title']. a namedtuple might also be neat here.
Upvotes: 0
Reputation: 28618
EDIT: I did not realize it's not a HTML page, so take a look at the correction by Chris. The below would work for HTML pages.
You can use:
titleTag = soup.html.head.title
or:
soup.findAll('title')
Take a look here:
Upvotes: 0