学习Python爬虫

背景

  在学习廖雪峰老师的python教程,和优达学城的数据分析课程,了解了python的使用,以及数据清洗和处理的一些方法后,想到了“数据获取”。然后就搜到了一篇讲解Python爬虫的系列教程 http://cuiqingcai.com/1052.html

  把基础只是学习完后,跟着做了两个实战:

   1. Python爬虫实战一之爬取糗事百科段子
   2. Python爬虫实战二之爬取百度贴吧帖子

练习

  这两个网站比较简单,页码可作为参数传过去,没有JS渲染。主要工作就是分析一下网站HTML源代码,然后用正则表达式去匹配一下自己想要的部分即可。

爬取糗事百科段子

正则表达式如下:

# 版本一,输出:作者、文字内容、点赞数、评论数
    regex = '<div.*?author.*?<a.*?<h2>(.*?)</h2>.*?<div.*?content.*?<span>(.*?)</span>.*?<span.*?stats-vote.*?><i.*?number.*?>(.*?)</i>(.*?)</span>.*?<span.*?stats-comments.*?<i.*?number.*?>(.*?)</i>(.*?)</a>'

# 版本二,输出:作者、文字内容、图片链接、点赞数、评论数
    regex = '<div.*?author.*?<a.*?<h2>(.*?)</h2>.*?<div.*?thumb.*?<img src="(.*?)".*?<div.*?content.*?<span>(.*?)</span>.*?<span.*?stats-vote.*?><i.*?number.*?>(.*?)</i>(.*?)</span>.*?<span.*?stats-comments.*?<i.*?number.*?>(.*?)</i>(.*?)</a>'

测试代码(参考原作者教程):

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date : 2017-06-16 11:08:07
# @Author : kk (zwk.patrick@foxmail.com)
# @Link : blog.csdn.net/PatrickZheng

import urllib, urllib2
import re

page = 1

url = 'http://www.qiushibaike.com/hot/page/' + str(page)
user_agent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36'
headers = {'User-Agent': user_agent}

try:
    request = urllib2.Request(url, headers = headers)
    response = urllib2.urlopen(request)
    content = response.read().decode('utf-8')

# 版本一,输出:作者、文字内容、点赞数、评论数
    regex = '<div.*?author.*?<a.*?<h2>(.*?)</h2>.*?<div.*?content.*?<span>(.*?)</span>.*?<span.*?stats-vote.*?><i.*?number.*?>(.*?)</i>(.*?)</span>.*?<span.*?stats-comments.*?<i.*?number.*?>(.*?)</i>(.*?)</a>'

    pattern = re.compile(regex ,re.S)

#1).*? 是一个固定的搭配,.和*代表可以匹配任意无限多个字符,加上?表示使用非贪婪模式进行匹配,也就是我们会尽可能短地做匹配,以后我们还会大量用到 .*? 的搭配。
#2)(.*?)代表一个分组,在这个正则表达式中我们匹配了五个分组,在后面的遍历item中,item[0]就代表第一个(.*?)所指代的内容,item[1]就代表第二个(.*?)所指代的内容,以此类推。
#3)re.S 标志代表在匹配时为点任意匹配模式,点 . 也可以代表换行符。

    items = re.findall(pattern, content)
    for item in items:
        great = re.search(u'好笑', item[3])
        comment = re.search(u'评论', item[5])
        print '作者:', item[0]
        print '内容:', item[1]
        if great:
            print '点赞数:', item[2]
        if comment:
            print '评论数:', item[4]
        print '---------------------------------'
except urllib2.HTTPError, e:
    if hasattr(e, 'code'):
        print e.code
except urllib2.URLError, e:
    if hasattr(e, 'reason'):
        print e.reason

爬取百度贴吧帖子

正则表达式如下:

  • 提取标题
re.compile('<h3 class="core_title_txt.*?>(.*?)</h3>', re.S)
  • 提取总页码
re.compile('<li class="l_reply_num.*?<span class="red">(.*?)</span>', re.S)
  • 提取正文
re.compile('<div id="post_content_.*?>(.*?)</div>', re.S)

另外,在设置文件标题时,遇到了编码问题,搜索到相关的解决方法,如下:

def setFileTitle(self, title):
    if title is None:
        title = self.defaultTitle
    # 使用open()时,这样写open(name.decode('utf-8'), 'w'),这样创建的中文文件名就没有乱码问题了
    # http://www.cnblogs.com/dragonisnotghost/p/4515581.html
    self.file = open((title + '.txt').decode('utf-8'), 'w+')

上述源码放在 Patrick-kk的github,一起学习交流

    原文作者:PatrickZheng
    原文地址: https://blog.csdn.net/PatrickZheng/article/details/73442458
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞