之前采用xpath和正则表达式对网页内容进行抓取,发现在有的地方不如人意,就采用了HTMLParser对页面进行解析,抓取需要的东西。HTMLParser有点不好的地方在于不能对startTag和endTag进行匹配。采用了两种方法进行抓取。
第一种,抓取成对的tag之间的内容,采用了queue.Queue保存handle_data。代码如下:
queue_data = queue.Queue(0)
def fetchData(tag):
while not queue_data.empty():
data = queue_data.get()
print(data, end = '')
print(end = '\n')
class MyHTMLParser(HTMLParser):
## def handle_entityref(self, ref):
## if ref == 'nbsp':
## print('The name is ', ref)
def handle_starttag(self, tag, attrs):
if tag =='li':
queue_data.put(tag)
def handle_endtag(self, tag):
if tag == 'li':
fetchData(tag)
def handle_data(self, data):
if not queue_data.empty():
queue_data.put(data)
第二种,抓取所有成对tag之间的内容,采用queue.LifiQueue保存data和starttag,当有endtag时,判断是否与之匹配的starttag,若有取出starttag和data。原本想list.pop()判断是否存在匹配的starttag,后来发现有starttag不一定有endtag。代码如下:
queue_data = queue.LifoQueue(0)
list_tag = []
def findTag(list, tag):
if list.count(tag):
data = list.pop()
while data != tag:
data = list.pop()
return(True)
else:
return(False)
def fetchData(tag):
data = queue_data.get()
if data == tag:
return
else:
print("Encountered a tag:", tag)
while data != tag:
print(data, end = '')
data = queue_data.get()
print(end = '\n')
class MyHTMLParser(HTMLParser):
## def handle_entityref(self, ref):
## if ref == 'nbsp':
## print('The name is ', ref)
def handle_starttag(self, tag, attrs):
if tag =='li':
queue_data.put(tag)
list_tag.append(tag)
def handle_endtag(self, tag):
if findTag(list_tag, tag):
fetchData(tag)
def handle_data(self, data):
queue_data.put(data)
测试的时候使用的百度微博,发现抓取的时候有些消息不能抓取。……
在starttag里,可以采用以下代码抓取tag的属性
## for i,value in attrs:
## print(value)