文章自动采集(腾讯新闻主页上所有新闻爬取分解目标一步地做 )

优采云 发布时间: 2021-08-29 00:05

  文章自动采集(腾讯新闻主页上所有新闻爬取分解目标一步地做

)

  昨天我用python写了一个天气预报采集,今天我在激动的同时写了一个新闻采集。

  目标是抓取腾讯新闻首页的所有新闻,获取每条新闻的名称、时间、来源和正文。

  接下来分解目标,一步一步来。

  第一步:抓取首页的所有链接,写入文件。

  按照上一篇文章的方法,可以轻松获取整个首页的文字内容。

  我们都知道html链接的标签是“a”,链接的属性是“href”,即获取html中所有的tag=a,attrs=href值。

  查了资料,一开始打算用HTMLParser,写出来了。但是它有一个问题,就是不能处理汉字。

  1 class parser(HTMLParser.HTMLParser):

2 def handle_starttag(self, tag, attrs):

3 if tag == 'a':

4 for attr, value in attrs:

5 if attr == 'href':

6 print value

  后来用了SGMLParser,就没有这个问题了。

  

  1 class URLParser(SGMLParser):

2 def reset(self):

3 SGMLParser.reset(self)

4 self.urls = []

5

6 def start_a(self,attrs):

7 href = [v for k,v in attrs if k=='href']

8 if href:

9 self.urls.extend(href)

  

  SGMLParser 需要为某个标签重新加载它的函数,这里是把所有的链接放到这个类的urls中。

  

  1 lParser = URLParser()#分析器来的

2 socket = urllib.urlopen("http://news.qq.com/")#打开这个网页

3

4 fout = file('urls.txt', 'w')#要把链接写到这个文件里

5 lParser.feed(socket.read())#分析啦

6

7 reg = 'http://news.qq.com/a/.*'#这个是用来匹配符合条件的链接,使用正则表达式匹配

8 pattern = re.compile(reg)

9

10 for url in lParser.urls:#链接都存在urls里

11 if pattern.match(url):

12 fout.write(url+'\n')

13

14 fout.close()

  

  这样,所有符合条件的链接都保存在 urls.txt 文件中。

  第 2 步:对于每个链接,获取其网页内容。

  很简单,打开urls.txt文件,一行一行读取即可。

  这里可能看起来没有必要,但是基于我强烈的解耦愿望,我还是果断地写在了文件中。如果以后使用面向对象编程,重构起来非常方便。

  获取网页内容比较简单,但是需要将网页内容保存在一个文件夹中。

  这里有几个新用法:

  

  1 os.getcwd()#获得当前文件夹路径

2 os.path.sep#当前系统路径分隔符(是这个叫法吗?)windows下是“\”,linux下是“/”

3

4 #判断文件夹是否存在,如果不存在则新建一个文件夹

5 if os.path.exists('newsdir') == False:

6 os.makedirs('newsdir')

7

8 #str()用来将某个数字转为字符串

9 i = 5

10 str(i)

  

  通过这些方法,将字符串保存到某个文件夹中的不同文件不再是一项艰巨的任务。

  第三步:枚举每个网页,根据正则匹配获取目标数据。

  以下方法用于遍历文件夹。

  1 #这个是用来遍历某个文件夹的

2 for parent, dirnames, filenames in os.walk(dir):

3 for dirname in dirnames

4 print parent, dirname

5 for filename in filenames:

6 print parent, filename

  遍历,读取,匹配,结果出来了。

  我用来提取数据的正则表达式是这样的:

  reg = '.*?(.*?).*?(.*?).*?<a .*?>(.*?)</a>.*?(.*?)'

  其实这个和上的新闻并不匹配,因为上面的新闻有两种格式,标签也有点不同,所以只能提取一种。

  还有一点是,通过正则表达式提取绝对不是主流的提取方式。如果需要采集other网站,就需要改正则表达式,比较麻烦。

  提取后观察发现正文部分总是混入一些不相关的信息,如“”“”等。所以我通过正则表达式切身体。

  

  1 def func(str):#谁起的这个名字

2 strs = re.split(".*?|.*?|&#[0-9]+;||", str)#各种匹配,通过“|”分隔

3 ans = ''

4 #将切分的结果组合起来

5 for each in strs:

6 ans += each

7 return ans

  

  这样基本上可以提取腾讯网站上的所有文字。

  到此,整个采集就结束了。

  显示我提取的结果(没有自动换行,隐藏在右侧):

  

  注意:

  1、 打开某个网址时,如果网址是坏的(打不开),不处理会报错。我只是简单的使用了处理异常的方法,估计应该还有其他方法。

  try:

socket = urllib.urlopen(url)

except:

continue

  2、Python “.”登录正则表达式可以匹配任何字符,除了“\n”。

  3、如何去掉字符串末尾的“\n”? Python的处理优雅到死!

  1 if line[-1] == '\n':

2 line = line[0:-1]

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线