腾讯新闻主页分解目标,一步地做(图)
优采云 发布时间: 2021-05-18 03:27腾讯新闻主页分解目标,一步地做(图)
昨天我用python编写了天气预报采集,今天我在利用天气预报的同时写了一条新闻采集。
目标是抓取腾讯新闻首页上的所有新闻,并获取每篇新闻文章的名称,时间,来源和文字。
接下来分解目标并逐步进行。
第1步:抓取主页上的所有链接并将其写入文件。
根据上一篇文章文章中的方法,您只需获取整个首页的文本内容即可。
我们都知道html链接的标签是“ a”并且链接的属性是“ href”,也就是说,要获取html中所有的tag = a,attrs = href值。
我检查了这些信息,计划首先使用HTMLParser,然后将其写出来。但这有一个问题,就是它不能处理汉字。
class parser(HTMLParser.HTMLParser):
def handle_starttag(self, tag, attrs):
if tag == 'a':
for attr, value in attrs:
if attr == 'href':
print value
后来使用了SGMLParser,它没有这个问题。
class URLParser(SGMLParser):
def reset(self):
SGMLParser.reset(self)
self.urls = []
def start_a(self,attrs):
href = [v for k,v in attrs if k=='href']
if href:
self.urls.extend(href)
SGMLParser需要为某个标签重新加载其功能,这里是将所有链接放在此类的url中。
lParser = URLParser()#分析器来的
socket = urllib.urlopen("http://news.qq.com/")#打开这个网页
fout = file('urls.txt', 'w')#要把链接写到这个文件里
lParser.feed(socket.read())#分析啦
reg = 'http://news.qq.com/a/.*'#这个是用来匹配符合条件的链接,使用正则表达式匹配
pattern = re.compile(reg)
for url in lParser.urls:#链接都存在urls里
if pattern.match(url):
fout.write(url+'\n')
fout.close()
通过这种方式,所有符合条件的链接都保存在urls.txt文件中。
第2步:获取每个链接的网页内容。
这非常简单,只需打开urls.txt文件并逐行读取即可。
在这里似乎没有必要,但是基于我对去耦的强烈渴望,我仍然果断地将其写在文件中。如果以后使用面向对象的编程,则重构非常方便。
获取网页的内容相对简单,但是您需要将网页的内容保存在一个文件夹中。
这里有几种新用法:
os.getcwd()#获得当前文件夹路径
os.path.sep#当前系统路径分隔符(是这个叫法吗?)windows下是“\”,linux下是“/”
#判断文件夹是否存在,如果不存在则新建一个文件夹
if os.path.exists('newsdir') == False:
os.makedirs('newsdir')
#str()用来将某个数字转为字符串
i = 5
str(i)
使用这些方法,将字符串保存到某个文件夹中的其他文件不再是困难的任务。
第3步:枚举每个网页并根据常规匹配获取目标数据。
以下方法用于遍历文件夹。
#这个是用来遍历某个文件夹的
for parent, dirnames, filenames in os.walk(dir):
for dirname in dirnames
print parent, dirname
for filename in filenames:
print parent, filename
遍历,阅读,匹配,结果就会出来。
我用于数据提取的正则表达式是这样的:
reg = '.*?(.*?).*?(.*?).*?<a .*?>(.*?)</a>.*?(.*?)'
<p style="color:#444444;font-family:tahoma, arial, sans-serif;background-color:#FFFFFF;">
其实这个并不能匹配到腾讯网的所有新闻,因为上面的新闻有两种格式,标签有一点差别,所以只能提取出一种。
另外一点就是通过正则表达式的提取肯定不是主流的提取方法,如果需要采集其他网站,就需要变更正则表达式,这可是一件比较麻烦的事情。
提取之后观察可知,正文部分总是会参杂一些无关信息,比如“...”“
”等等。所以我再通过正则表达式将正文切片。
def func(str):#谁起的这个名字
strs = re.split(".*?|.*?|&#[0-9]+;||", str)#各种匹配,通过“|”分隔
ans = ''
#将切分的结果组合起来
for each in strs:
ans += each
return ans</p>
这样,基本上可以提取腾讯网站上的所有文本。
至此,整个采集结束了。
告诉我我提取的结果(没有自动换行,隐藏在右侧):
注意:
1、当打开某个URL时,如果URL错误(无法打开),则如果未处理,将报告错误。我只是使用处理异常的方法,估计应该还有其他方法。
try:
socket = urllib.urlopen(url)
except:
continue
2、“。”登录Python正则表达式可以匹配任何字符,但“ \ n”除外。
3、如何删除字符串末尾的“ \ n”? Python的处理是如此优美!
if line[-1] == '\n':
line = line[0:-1]