仿9GAG制作过程(二)
有话要说:
这次准备讲述用python爬虫以及将爬来的数据存到MySQL数据库的过程,爬的是煎蛋网的无聊图。
成果:
准备:
- 下载了python3.7并配置好了环境变量
- 下载了PyCharm作为开发python的IDE
- 安装了MySQL客户端以及服务端
- 安装了Navicat客户端
- 通过pip命令下载安装beautifulsoup,selenium以及pymysql模块,pip命令如下:
pip install beautifulsoup4
pip install selenium
pip install pymysql
观察“无聊图”网页源码:
先上部分源码:
<li id="comment-3838846">
<div>
<div class="row">
<div class="author"><strong
title="防伪码:fc33b015c2b4d50cd1a23007810b09f049f1407d" class="orange-name">猴子</strong> <br>
<small><a href="#footer" title="@回复"
onclick="document.getElementById('comment').value += '@<a href="//jandan.net/pic/page-185#comment-3838846">猴子</a>: '">@4 days ago</a></span></small>
</div>
<div class="text"><span class="righttext"><a href="//jandan.net/pic/page-185#comment-3838846">3838846</a></span><p>这个盖字是怎么翻译出来的<br />
<img src="//img.jandan.net/img/blank.gif" onload="jandan_load_img(this)" /><span class="img-hash">Ly93dzMuc2luYWltZy5jbi9tdzYwMC8wMDZYTkVZN2d5MWZydm84MHg0Mm1qMzFrdzIzdmF6cS5qcGc=</span></p>
</div>
<div class="jandan-vote">
<span class="comment-report-c">
<a title="投诉" href="javascript:;" class="comment-report" data-id="3838846">[投诉]</a>
</span>
<span class="tucao-like-container">
<a title="圈圈/支持" href="javascript:;" class="comment-like like" data-id="3838846" data-type="pos">OO</a> [<span>52</span>]
</span>
<span class="tucao-unlike-container">
<a title="叉叉/反对" href="javascript:;" class="comment-unlike unlike" data-id="3838846" data-type="neg">XX</a> [<span>13</span>] <a href="javascript:;" class="tucao-btn" data-id="3838846"> 吐槽 [16] </a>
</span>
</div>
</div>
</div>
</li>
发现在源码里边图片链接并没有直接显示出来,而是在js中加载的。因此,不能用普通的爬虫方式来获取图片链接。
看了许多博客,最终决定采用Python3+BeautifulSoup+selenium的方式来抓取。
selenium用来获取网页链接数据,BeautifulSoup用来解析获取的网页源码。
selenium相当于一个小型浏览器,可以直接获取完整的网页源码,获取之后的网页源码如下所示:
<li id="comment-3838846">
<div>
<div class="row">
<div class="author"><strong title="防伪码:fc33b015c2b4d50cd1a23007810b09f049f1407d" class="orange-name">猴子</strong> <br>
<small><a href="#footer" title="@回复" onclick="document.getElementById('comment').value += '@<a href="//jandan.net/pic/page-185#comment-3838846">猴子</a>: '">@4 days ago</a></small>
</div>
<div class="text"><span class="righttext"><a href="//jandan.net/pic/page-185#comment-3838846">3838846</a></span><p>这个盖字是怎么翻译出来的<br>
<a href="//ww3.sinaimg.cn/large/006XNEY7gy1frvo80x42mj31kw23vazq.jpg" target="_blank" class="view_img_link">[查看原图]</a><br><img src="http://ww3.sinaimg.cn/mw600/006XNEY7gy1frvo80x42mj31kw23vazq.jpg" style="max-width: 100%; max-height: 450px;"></p>
</div>
<div class="jandan-vote">
<span class="comment-report-c">
<a title="投诉" href="javascript:;" class="comment-report" data-id="3838846">[投诉]</a>
</span>
<span class="tucao-like-container">
<a title="圈圈/支持" href="javascript:;" class="comment-like like" data-id="3838846" data-type="pos">OO</a> [<span>52</span>]
</span>
<span class="tucao-unlike-container">
<a title="叉叉/反对" href="javascript:;" class="comment-unlike unlike" data-id="3838846" data-type="neg">XX</a> [<span>13</span>] <a href="javascript:;" class="tucao-btn" data-id="3838846"> 吐槽 [16] </a>
</span>
</div>
</div>
</div>
</li>
注意到,class="row"的div是我们需要的,并且不包含我们不需要的部分,因此就可以通过class="row"来获取需要的数据。
又因为一条段子包含的信息有:一个标题(有些有有些没有),若干张图片,点赞数,点踩数。因此设计数据库表如下:
数据库表设计:
因为以上的信息,故设计了两张表。
一张表用来存放段子的基本信息,包括主键、标题、点赞数、点踩数;
另一张表用来存放段子包含的图片链接,包括主键、图片链接、段子主键。
用段子主键来相互关联,主要SQL语句如下:
CREATE TABLE `news` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '段子标识',
`title` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '段子标题',
`like` int(11) DEFAULT NULL COMMENT '点赞数',
`unlike` int(11) DEFAULT NULL COMMENT '点踩数',
PRIMARY KEY (`id`)
) CREATE TABLE `news_pics` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '图片标识',
`url` varchar(255) DEFAULT NULL COMMENT '图片链接',
`newsid` int(11) NOT NULL COMMENT '段子标识',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=319 DEFAULT CHARSET=utf8;
主体部分:
接着,阅读了Python爬取煎蛋妹子图以及python+selenium+PhantomJS爬取网页动态加载内容之后,实现了利用python进行抓取数据解析数据的过程,先上代码:
# coding=utf-8
import re
import pymysql
from bs4 import BeautifulSoup
from selenium import webdriver base_url = "http://jandan.net/pic/page-"
driver = webdriver.PhantomJS() items = []
urls = ["http://jandan.net/pic/page-{}#comments".format(str(i)) for i in range(50689352, 50689355)] db = pymysql.connect(host="localhost", user="root", password="root", db="imitating9gag", charset="utf8")
cursor = db.cursor() sql_news = '''INSERT INTO `imitating9gag`.`news` (`id`, `title`, `like`, `unlike`) VALUES ('%d', '%s', '%d', '%d')'''
sql_pics = '''INSERT INTO `imitating9gag`.`news_pics` (`id`, `url`, `newsid`) VALUES ('%d', '%s', '%d')''' if __name__ == "__main__":
for url in urls:
driver.get(url)
data = driver.page_source
soup = BeautifulSoup(data, "html.parser")
divs = soup.findAll('div', attrs={'class': 'row'}) # 遍历所有的项
for div in divs:
# 'title'代表的是文字,'urls'代表的是图片的集合,'like'代表的是点赞数,'unlike'代表的是踩
item = {}
urls = [] item['like'] = div.find('span', attrs={'class': 'tucao-like-container'}).find('span').string
item['unlike'] = div.find('span', attrs={'class': 'tucao-unlike-container'}).find('span').string paragraph = div.find(attrs={'class': 'text'}).find("p") # 获取所有的图片链接
links = paragraph.select("a.view_img_link")
for link in links:
urls.append("http:" + link.get('href'))
item['urls'] = urls # 获取最开始的文字部分
title = re.search('<p>[\s\S]+?<a', str(paragraph)) if title is not None and title.group()[3:-8] is not None \
and title.group()[3:-8].find('view_img_link') == -1:
item['title'] = title.group()[3:-8]
else:
item['title'] = "" items.append(item) i = 1
j = 1
try:
for item in items:
# 插入新闻数据
cursor.execute(sql_news % (i, item['title'], int(item['like']), int(item['unlike'])))
# 插入图片数据
for tempUrl in item['urls']:
cursor.execute(sql_pics % (j, tempUrl, i))
j = j+1
i = i+1
db.commit()
except Exception as e:
print(e)
print(item)
db.rollback()
db.close()
注意点:
- 在用pymysql的时候,如果插入的数据有中文,则在connect的时候需要设置charset,见13行
- 44行在获取title的时候用了正则表达式,最开始直接用[.+]并不会匹配换行符,因此换成了[\s\S],\s匹配空白符,\S匹配非空白符,因此可以匹配所有的字符。
- 最开始准备使用MySQLdb来操作数据库,但是python3不支持,于是换成了pymysql来操作数据库
至此,后台数据已经获取完成,接下来是后台接口的开发,准备采用Java的Servlet来实现后台接口的开发。
反思:
- 对python语法掌握的不足,一些简单的语法需要通过查询才知道怎么用,需要找一个时间完整的学习一边python语法
- 对正则表达式的使用不熟练,以后需要加强对正则表达式使用的练习
- 本次代码仅作学习用,没有进行优化,也没有考虑到一些特殊的情况
- 通过这次学习到了python语法+爬虫基本步骤+数据库的整体设计+解析网页源码
- 如果title中有表情,保存数据库会报错,该问题正在解决
大家如果有什么疑问或者建议可以通过评论或者邮件的方式联系我,欢迎大家的评论~
仿9GAG制作过程(二)的更多相关文章
- 仿9GAG制作过程(一)
有话要说: 准备开始学习Android应用程序的一个完整的设计过程.准备做一个仿9GAG的APP,前端界面设计+后台数据爬虫+后台接口设计,整个流程体验一遍.今天准备先把前端界面的框架给完成了. 成果 ...
- 仿9GAG制作过程(四)
有话要说: 这次主要讲述主页面下拉刷新和上拉加载功能的实现. 主要是使用了SwipeRefreshLayout的布局方式,并在此基础上通过RecyclerView的特性增加了上拉加载的功能. 成果: ...
- 仿9GAG制作过程(五)
有话要说: 在做完了数据展示功能之后,就想着完善整个APP.发现现在后台非常的混乱,有好多点都不具备,比方说:图片应该有略缩图和原图,段子.评论.点赞应该联动起来,段子应该有创建时间等. 于是就重新设 ...
- 仿9GAG制作过程(三)
有话要说: 这次准备讲述后台服务器的搭建以及前台访问到数据的过程. 成果: 准备: 安装了eclipse 安装了Tomcat7 安装了数据库管理工具:Navicat 搭建服务器: 用eclipse直接 ...
- [PCB制作] 1、记录一个简单的电路板的制作过程——四线二项步进电机驱动模块(L6219)
前言 现在,很多人手上都有一两个电子设备,但是却很少有人清楚其中比较关键的部分(PCB电路板)是如何制作出来的.我虽然懂点硬件,但是之前设计的简单系统都是自己在万能板上用导线自己焊接的(如下图左),复 ...
- Android实训案例(九)——答题系统的思绪,自己设计一个题库的体验,一个思路清晰的答题软件制作过程
Android实训案例(九)--答题系统的思绪,自己设计一个题库的体验,一个思路清晰的答题软件制作过程 项目也是偷师的,决心研究一下数据库.所以写的还是很详细的,各位看官,耐着性子看完,实现结果不重要 ...
- BabyLinux制作过程详解
转:http://www.360doc.com/content/05/0915/14/1429_12641.shtml BabyLinux制作过程详解 作者:GuCuiwen email:win2li ...
- ASP.NET Web API 过滤器创建、执行过程(二)
ASP.NET Web API 过滤器创建.执行过程(二) 前言 前面一篇中讲解了过滤器执行之前的创建,通过实现IFilterProvider注册到当前的HttpConfiguration里的服务容器 ...
- ASP.NET Web API 控制器创建过程(二)
ASP.NET Web API 控制器创建过程(二) 前言 本来这篇随笔应该是在上周就该写出来发布的,由于身体跟不上节奏感冒发烧有心无力,这种天气感冒发烧生不如死,也真正的体会到了什么叫病来如山倒,病 ...
随机推荐
- Redis两种方式实现限流
案例-实现访问频率限制: 实现访问者 $ip 在一定的时间 $time 内只能访问 $limit 次. 非脚本实现 private boolean accessLimit(String ip, int ...
- Java实现桶排序和基数排序
桶排序代码: import java.util.Arrays; /** * 桶排序 * 工作的原理是将数组分到有限数量的桶里 * 每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序 ...
- freekan5.9电影网站安装及源码分享
Freekan是一套目前非常火的电影网站系统,全自动采集,支持对接公众号 服务器环境:centos7,宝塔面板,php7.1(重要),nignx,mysql 1.首先上传压缩包到网站目录,然后解压 2 ...
- [Swift]LeetCode623. 在二叉树中增加一行 | Add One Row to Tree
Given the root of a binary tree, then value v and depth d, you need to add a row of nodes with value ...
- python 模拟豆瓣登录(豆瓣6.0)
最近在学习python爬虫,看到网上有很多关于模拟豆瓣登录的例子,随意找了一个试了下,发现不能运行,对比了一下代码和豆瓣网站,发现原来是豆瓣网站做了修改,增加了反爬措施. 首先看下要模拟登录的网站: ...
- 有了这 4 大特性,CDN 好用到飞起
随着 CDN 市场的快速发展和网络新技术的不断涌现,目前的 CDN 已不仅仅是当初简单的内容分发,同时也是新特性研发.新技术推广及实践的平台.这些新技术.新特性,或者能够保障 CDN 安全性,或是提升 ...
- Java面试题:小白不得不懂的斐波那契数列
很长一段时间里,我都非常疑惑:“我写的技术文章不差啊,有内容的同时还很有趣,不至于每篇只有区区几十个人读啊?为什么有些内容简单到只有一行注册码的文章浏览量反而轻松破万?”这样的疑惑如鲠在喉啊!写技术博 ...
- python:pip命令使用
pip命令安装库 pip install 库名 使用pip命令更新库 pip install --upgrade 库名 比如更新scikit-learn包 pip install --upgrade ...
- 理解和使用Promise.all和Promise.race
一.Pomise.all的使用 Promise.all可以将多个Promise实例包装成一个新的Promise实例.同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回 ...
- Linux 虚拟内存
查看进程占用内存情况: ps -aux VSZ表示占用虚拟内存单位KBRSS表示占用物理内存单位KB 添加swap文件大小为4G 内部存储块每块1M dd if=/dev/zero of=/swap ...