【菜鸟致敬】爬取豆瓣的短评(⊙o⊙)…

提示,颜色不同是因为不是同一个时候写的,这个时候写的就选绿色吧,比较好看

因为需要一点数据,所以就去爬取一点豆瓣短评的数据。因为短评页面是生成的静态html,还是很容易爬虫数据的,其中发现了问题每部电影短评在同一条件下最多只能查阅500条,即使你已经登录豆瓣,当然,如果你没有登录只能查看前面的200条短评。

其实到这里我本着不造轮子的想法,找到了网上大佬写的代码,以为copy一下就可以了,然额事情并没有你想象中的那么简单。贴一下其中一份代码,吐槽的事情交给你们。(终于知道了加上代码风格的片段的办法了

import requests  
import re 
import pandas as  
 
pdurl_first='https://movie.douban.com/subject/26363254/comments?start=0' 
head={'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/59.0.3071.109 Chrome/59.0.3071.109 Safari/537.36'} 
html=requests.get(url_first,headers=head,cookies=cookies) 
 
cookies={'cookie':'你自己的cookie'}  #也就是找到你的账号对应的cookie 
 
reg=re.compile(r'<a href="(.*?)&amp;.*?class="next">') #下一页 
 
ren=re.compile(r'<span class="votes">(.*?)</span>.*?comment">(.*?)</a>.*?</span>.*?<span.*?class="">(.*?)</a>.*?<span>(.*?)</span>.*?title="(.*?)"></span>.*?title="(.*?)">.*?class=""> (.*?)\n',re.S)  #评论等内容 
 
while html.status_code==200: 
 url_next='https://movie.douban.com/subject/26363254/comments'+re.findall(reg,html.text)[0]                              
zhanlang=re.findall(ren,html.text) 
data=pd.DataFrame(zhanlang) 
data.to_csv('/home/wajuejiprince/文档/zhanlang/zhanlangpinglun.csv', header=False,index=False,mode='a+') #写入csv文件,'a+'是追加模式 
data=[] 
zhanlang=[] 
html=requests.get(url_next,cookies=cookies,headers=head)

其实看到第三行就感觉怪怪的,但考虑到我是弱鸡,毕竟Python语法是我在不停报错中外加看demo中自己熟悉的吧,可能这是一种高级的用法。

运行一下,报错实在太多,只能看一下源码啊,看不懂,无奈放弃,只能自己造轮子。

自己看了看链接样式和短评的样式,开始自己造轮子,当然这个时候我还没意识到豆瓣短评最多只能爬取500条了。

开始的时候选择了requests+re大法,一切很OK。稍微不好的一点就是因为正则表达式涉及换行的匹配,很容易将多的内容匹配进来

好滴,楼上图太丑,再放一张

短评是这样的,正则是这样的,考虑到自己弱鸡,无奈换一个思路,xpath没看过,只能BeautifulSoup。一切很ok,下面是正则变表达式,有前辈指点一下就更好了。

<p class="">((.|\n)*?)</p>

当然这是在计科的师兄支援下,改进了一下自己的轮子,放代码(湄公河)。代码是能够正常操作了,稍微改进一下就是一个可以滚的轮子了,其他电影的短评也可以拿到了。代码我会继续改进,毕竟我写的东西一般从v1.0到v1.9才会截止。

# 不知道什么原因,导入不了同文件夹模块,所以集合在一个py文件里面
import requests
import pymysql
from bs4 import BeautifulSoup

conn = pymysql.connect(host='127.0.0.1', user="root", passwd='0823', charset='utf8')
cursor = conn.cursor()
cursor.execute('use yingping;')
cursor.execute('drop table if exists mgh;')
cursor.execute('create table if not exists mgh (pinglun text);')
mgh_head = 'https://movie.douban.com/subject/25815034/comments?start='
mgh_tail = '&limit=20&sort=new_score&status=P&percent_type='

header = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0'
}
cookie = {
    'Cookie': 'll="118281"; bid=kcwGKisJCzs; __yadk_uid=u3uHskig8KBwzvtU043Bvda3sLkYN4jO; ps=y; _pk_ref.100001.4cf6=%5B%22%22%2C%22%22%2C1524753458%2C%22https%3A%2F%2Fwww.douban.com%2F%22%5D; __utmt=1; _vwo_uuid_v2=D0B59412967E6C51F8AC6A90E8A9CE669|c5179d30bf2a1df782b34129bf7f0af2; as="https://movie.douban.com/subject/25815034/comments?start=320&limit=20&sort=new_score&status=P&percent_type="; dbcl2="152650172:7EdGrc9pqS4"; ck=WIUd; ap=1; __utma=30149280.853980687.1524740480.1524746415.1524753459.3; __utmb=30149280.2.10.1524753459; __utmc=30149280; __utmz=30149280.1524740480.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utma=223695111.1616095102.1524740480.1524746415.1524753459.3; __utmb=223695111.0.10.1524753459; __utmc=223695111; __utmz=223695111.1524740480.1.1.utmcsr=douban.com|utmccn=(referral)|utmcmd=referral|utmcct=/; _pk_id.100001.4cf6=87b9b010fb017976.1524740481.4.1524753790.1524751409.; _pk_ses.100001.4cf6=*; push_noty_num=0; push_doumail_num=0'
}
mgh_urls = []
# regex = re.compile('<p class="">((.|\n)*?)</p>')
for i in range(0, 1000, 20):
    mgh_urls.append(mgh_head + str(i) + mgh_tail)
#
# for url in mgh_urls:
#     print(url)
for i, mgh_url in zip(range(0, 50), mgh_urls):
    mgh_resp = requests.get(url=mgh_url, cookies=cookie)
    mgh_resp.encoding = 'utf-8'
    soup = BeautifulSoup(mgh_resp.text,'lxml')
    mgh_result = soup.find_all(name='p')

    for i in range(3,23):
        print(mgh_result[i].string)
    # mgh_result = regex.findall(mgh_resp.text)
    # print(mgh_result)
    #     with open('mgh.txt', mode='w', encoding='utf-8') as f:
   #                    for it in mgh_result:
    #         f.write(str(mgh_result[i].string))
    #     f.close()

        try:
            cursor.execute("insert into mgh(pinglun) values(%s);",str(mgh_result[i].string))
        except:
            conn.commit()
            conn.close()
conn.commit()
conn.close()

为什么没有考虑到class属性,是因为它的class为空值,对最后结果没有影响。

考虑到速度,所以选择了lxml解析器(

多线程不太会用)。当然豆瓣不反爬,也就没有设置代理。

不过很遗憾,利用cookie模拟登陆失败了(虽然我看了每次的cookie值是一模一样的,可能少了啥东西吧,利用的是最上面的代码的模拟登陆的思路),导致每次只能爬到200条有效信息。

Python看的脑阔疼。

经过俩天的版本(这篇俩天前开始写,之后没动过了),终于有了一个比较好的版本,不说了,直接放代码

# 不知道什么原因,导入不了,所以集合在一个py文件里面
import time
import requests
import csv
from bs4 import BeautifulSoup
head = 'https://movie.douban.com/subject/'
middle = '/comments?start='
zr_tail = '&limit=20&sort=new_score&status=P&percent_type='
names = []
header = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0'
}

zr_urls = ['最热']
def createUrls():
    for j in range(1, 34, 2):
        name = names[j]
        for i in range(0, 100, 20):
            # if i < 100:
            zr_urls.append(head + str(name) + middle + str(i) + zr_tail)  # 构建最热默认
    

def readName():
    with open('编号.txt', mode='r', encoding='utf-8') as f:
        for i in f.readlines():
            i = i.strip('\n')
            names.append(i)
        # print(names)
def get_comments(urls):
    global sort_name  #
    sort_name = urls[0]  # 从第一个元素得到分类方式
    del urls[0]  # 删掉
    for url in urls:
        comment_list = []
        try:
            resp = requests.get(url=url, headers=header)
            time.sleep(5)  # 亲测大概4000条数据被封ip,这样的话不会封ip
            print('正在请求 ' + url)
            if resp.status_code != 200:
                print("啊哈哈哈,ip又被封了,等一会我们再来")
                time.sleep(5)
                resp = requests.get(url=url, headers=header)
        except:
            continue
        resp.encoding = 'utf-8'  # 使用utf-8编码
        # print(resp.text)
        soup = BeautifulSoup(resp.text, 'lxml')
        global video_name
        video_name = soup.find(name='title').string
        print(video_name)
        global result
        result = soup.find_all(name='p')  # 所有的评论
        for item in result[2:22]:
            comment_list.append(item.get_text())  # 找到所有p标签下的文本,不迭代
        # print(len(result))  # 打印长度,用于debug
        if urls.index(url) % 5 == 0:
            with open(video_name + sort_name + '.csv', mode='w',
                      encoding='utf-8') as f:  # 使用utf-8格式编码,直接打开csv文件会乱码,需要指定编码
                f.write(video_name + "\n")
                f.close()
        with open(video_name + sort_name + '.csv', mode='a', encoding='utf-8') as f:
            write = csv.writer(f)
            write.writerow(comment_list)
            f.close()
            print("完成了" + video_name + "这一页,咋们继续!")
            print("--------------------")
readName()
createUrls()
get_comments(zr_urls)

菜鸟级代码,大概还会改进的地方:①写一个抓取豆瓣影评对应id的接口(编号.txt文件请在后台发送 编号 获取)②使用mysql存储爬到的短评(存取txt,csv和mysql的函数实际已经写好)③使用多线程

备注:去掉请求后面的睡眠,大概会在200个页面后被封ip,当天会被列入黑名单,之后请求一旦过快就会被立刻封ip。

因为代码是我一个人码的,所以很随意,毕竟自己能看懂的代码才是好代码。

本文适合入门级菜鸟程序猿。

原文发布于微信公众号 - Python与MySQL(Python_Rick)

原文发表时间:2018-04-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏更流畅、简洁的软件开发方式

我的分页控件(未完,待续)——控件件介绍及思路

分页控件新版本,基于.net2.0。 http://www.cnblogs.com/jyk/archive/2008/07/05/1236692.html ...

22470
来自专栏更流畅、简洁的软件开发方式

【开源】我的分页控件正式命名为QuickPager ASP.NET2.0分页控件

分页控件正式命名为 QuickPager ASP.NET2.0分页控件 。 版本号:2.0.0.1 Framework:.net2.0 分页方式:PostB...

22550
来自专栏林欣哲

SpringBoot的微信点餐系统后台开发要点

项目设计 角色划分 买家(微信端) 卖家(PC端) 功能分析 ? 关系 ? 部署架构 ? 架构和基础框架 演进:单一应用架构->垂直应用架构->分布式服务架构-...

1.9K400
来自专栏林德熙的博客

win10 uwp 使用油墨输入 保存,修改,加载inkUWP 手写清理笔画手写识别无法识别手写语音

现在很多人还是使用笔和纸来记录,那么可以在电脑输入方式和之前使用的方式一样,很多用户觉得会方便。在win10 我们有一个简单的方法去让用户输入,InkCanva...

26410
来自专栏黑泽君的专栏

从零讲JAVA ,给你一条清晰地学习道路!该学什么就学什么!!

 原文链接:https://zhuanlan.zhihu.com/p/25296859

11020
来自专栏Java后端技术栈

你应该知道的缓存进化史!

本文是上周去技术沙龙听了一下爱奇艺的Java缓存之路有感写出来的。先简单介绍一下爱奇艺的java缓存道路的发展吧。

15010
来自专栏Crossin的编程教室

Python 爬虫爬取美剧网站

一直有爱看美剧的习惯,一方面锻炼一下英语听力,一方面打发一下时间。之前是能在视频网站上面在线看的,可是自从广电总局的限制令之后,进口的美剧英剧等貌似就不在像以前...

43670
来自专栏Hongten

python开发_常用的python模块及安装方法

adodb:我们领导推荐的数据库连接组件 bsddb3:BerkeleyDB的连接组件 Cheetah-1.0:我比较喜欢这个版本的cheetah cherry...

46430
来自专栏信安之路

我是如何找到 Google Colaboratory 中的一个 xss 漏洞的

在本文中,我来讲讲我碰到的一个有趣的 XSS。2018 年 2 月,我在 google 的一个网络应用中发现了这个 XSS。这篇文章我不希望只是直接写出这个 X...

12800
来自专栏技术小黑屋

如何从UA分辨出Android设备类型

随着Android设备增多,不少网站都开始设备Android设备,而Android主流设备类型以手机和平板为主。网站在适配时通过User Agent(用户代理,...

13440

扫码关注云+社区

领取腾讯云代金券