Python中的网页抓取

0 投票
3 回答
622 浏览
提问于 2025-04-16 07:31

我现在正在尝试从一个网站上抓取信息,并把这些信息放到一个字典里。我使用的是urllib2和BeautifulSoup这两个工具。不过,我不知道怎么解析网页的源代码,以便获取我想要的信息,并把它读入字典中。我想要的信息在源代码中显示为 <title>Nov 24 | 8:00AM | Sole In. Peace Out. </title>。我在考虑使用正则表达式来读取这一行,把时间和日期转换成日期时间格式,然后再解析这一行,把数据读入字典。字典的输出应该大致是这样的:

[ { "date": datetime(2010, 11, 24, 23, 59), "title": "Sole In. Peace Out.", } ]

当前代码:

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)

抱歉写了这么多文字,感谢你的时间和帮助!

3 个回答

0
>>> 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.'}

注意,这里也包括了一天中的时间。

然后,我想你是想要所有的项目,

>>> 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'}]

如果你想处理更复杂的年份问题,你是可以做到的。你明白我的意思了。

最后补充一下:使用生成器会是个不错的选择。

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.
0

编辑:我之前没意识到这不是一个HTML页面,所以请看看Chris的修正。下面的内容适用于HTML页面。

你可以使用:

titleTag = soup.html.head.title

或者:

soup.findAll('title')

可以看看这里:

1

大概是这样的..

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() 会返回所有找到的元素.. 所以你可以把它当作普通的列表来使用。

这样就差不多可以了 :)

编辑:小修正

编辑2:根据下面的评论做的修正

撰写回答