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

优采云 发布时间: 2021-10-20 14:14

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

)

  昨天用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 步:对于每个链接,获取其 Web 内容。

  很简单,直接打开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)

  

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

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

  下面的方法用于遍历文件夹。

  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人工客服


线