爬虫抓取段子模拟订阅功能

前期准备

linux与vagrant

写python个人感觉还是比较偏向于linux,老实说现在除了打打游戏之外会用到window之外,上课,学习,工作等等都已转到linux,因为linux给了我更大的自由和权限。所以我在我的macbook通过了virtualbox与vagrant搭建了一个虚拟环境,其实这样也方便我的备份和随时切换。

python与virtualenv

python的本班是2.7.9,使用virtualenv开启了一个独立的Python环境,使各个python项目之间的依赖等等不互相影响。

版本一,抓取百思不得姐的段子

bsbdj.png-249.6kB

请求地址

http://www.budejie.com/new-text/2

构造请求页面
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import urllib2

page = 1
url = 'http://www.budejie.com/new-text/' + str(page)
try:
    de_url = url + str(page)
    request = urllib2.Request(url)
    response = urllib2.urlopen(request)
    print response.read().decode('utf-8')
except urllib2.URLError, e:
    if hasattr(e, "code"):
        print e.code
    if hasattr(e, "reason"):
        print e.reason

居然失败了

403
Forbidden

加上headers验证

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import urllib2

page = 1
url = 'http://www.budejie.com/new-text/' + str(page)
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = {'User-Agent': user_agent}
try:
    de_url = url + str(page)
    request = urllib2.Request(de_url, headers=headers)
    response = urllib2.urlopen(request)
    print response.read().decode('utf-8')
except urllib2.URLError, e:
    if hasattr(e, "code"):
        print e.code
    if hasattr(e, "reason"):
        print e.reason

成功了打印了html

抓取某一页的所有段子

审查元素

f12.png-215.3kB

可以看到 段子都包含在帖子列表下 <div class="j-r-list"></div>下,一个段子都为一个li。先看看发送邮件的效果。

xiaoguo.png-194.1kB

那也就是抓取头像,作者,内容。这里直接采用正则来匹配,紧接上面的代码。

content = response.read().decode('utf-8')
pattern = re.compile(r'<div.*?u-img">.*?<img.*?u-logo.*?data-original="(.*?)".*?<div.*?u-txt.*?_blank">(.*?)</a>.*?<div.*?j-r-list-c-desc">.*?html">(.*?)</a>.*?.*?j-r-list-tool-l-up.*?<span>(.*?)</span>.*?</div>', re.S)
outputs = re.findall(pattern, content)
        for output in outputs:
            print output[1] + ':' + output[2] + '-->' + output[1] + '\n'

关于上面的正则表达式的几点说明

  • .? 是一个固定的搭配,.和代表可以匹配任意无限多个字符,加上?表示使用非贪婪模式进行匹配,也就是我们会尽可能短地做匹配,以后我们还会大量用到 .*? 的搭配。

  • (.?)代表一个分组,在这个正则表达式中我们匹配了三个分组,在后面的遍历outputs中,output[0]就代表第一个(.?)所指代的内容,output1就代表第二个(.*?)所指代的内容,以此类推。

  • re.S 标志代表在匹配时为点任意匹配模式,点 . 也可以代表换行符。

这里已经实现了抓取该页下的段子了。

版本二,抓取糗事百科的段子

qsbk.png-204kB

请求地址 http://www.qiushibaike.com/hot/page/2

审查一下元素

csbkf12.png-364kB

可以发现每个段子的都是一个<div class="article block untagged mb15"

这里就使用了BeautifulSoup来抓取。

关于如何安装BeautifulSoup,可直接用pip安装。这里的BeautifulSoup版本是第4版。

抓取所有段子
from bs4 import BeautifulSoup

page = 1
    url = 'http://www.qiushibaike.com/hot/page/' + str(page)
    user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
    headers = {'User-Agent': user_agent}
    try:
        request = urllib2.Request(url, headers=headers)
        response = urllib2.urlopen(request)
        content = response.read().decode('utf-8')
        soup = BeautifulSoup(content, "lxml")
        items = soup.find_all(name='div', class_='article block untagged mb15')
        print items
        
    except urllib2.URLError, e:
        if hasattr(e, "code"):
            print e.code
        if hasattr(e, "reason"):
            print e.reason

关于BeautifulSoup的使用方法可以看它的官方文档。

抓取单个段子信息
def print_qiushi(item):
    # 过滤有图片的段子
    if item.find('div', class_='thumb'):
        return
    # 过滤有视频的段子
    if item.find(name="div", class_='video_holder'):
        return
    # 获取揭晓这条段子的用户名
    author = item.find("div", class_='author')
    if author != None:
        author = author.get_text().strip()
    else:
        author = 'anonymous'

    # 获取用户名头像
    avatar = item.find("img")
    img = avatar['src']
    if str(img).strip() == '':
        img = "http://mpic.spriteapp.cn/profile/large/2016/12/03/58427c5196782_mini.jpg"

    # 获取段子内容
    content = item.find("div", class_='content').get_text().strip()

    data = {
        'author': '%s' % author,
        'img': '%s' % img,
        'content': '%s' % content,
        'created_time': '%s' % time.strftime("%Y-%m-%d %H:%M:%S")
    }
    return data
完整代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Filename : get_csbk
# @Author   : asd
# @Date     : 2017-02-23 17:40

import urllib2

import time
from bs4 import BeautifulSoup
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

from Utils import myutils

def main():
    page = 1
    url = 'http://www.qiushibaike.com/hot/page/' + str(page)
    user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
    headers = {'User-Agent': user_agent}
    try:
        request = urllib2.Request(url, headers=headers)
        response = urllib2.urlopen(request)
        content = response.read().decode('utf-8')
        soup = BeautifulSoup(content, "lxml")
        items = soup.find_all(name='div', class_='article block untagged mb15')
        result = list()
        for item in items:
            if item:
                result.append(print_qiushi(item))
        print result


    except urllib2.URLError, e:
        if hasattr(e, "code"):
            print e.code
        if hasattr(e, "reason"):
            print e.reason


def print_qiushi(item):
    # 过滤有图片的段子
    if item.find('div', class_='thumb'):
        return
    # 过滤有视频的段子
    if item.find(name="div", class_='video_holder'):
        return
    # 获取揭用户名
    author = item.find("div", class_='author')
    if author != None:
        author = author.get_text().strip()
    else:
        author = 'anonymous'

    # 获取用户头像
    avatar = item.find("img")
    img = avatar['src']
    if str(img).strip() == '':
        img = "http://mpic.spriteapp.cn/profile/large/2016/12/03/58427c5196782_mini.jpg"

    # 获取段子内容
    content = item.find("div", class_='content').get_text().strip()

    data = {
        'author': '%s' % author,
        'img': '%s' % img,
        'content': '%s' % content,
        'created_time': '%s' % time.strftime("%Y-%m-%d %H:%M:%S")
    }
    return data

if __name__ == '__main__':
    main()

未完待续

转载于:https://my.oschina.net/asd945/blog/890983

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值