本文是《Web scraping with python》的简单的学习笔记,默认在python 3.0版本上运行,所以在运行时使用python3 name.py命令。
第一章 第一个网络爬虫
本章给出一个简单的web 爬虫代码段如下:
from urllib.request import urlopen from urllib.error import HTTPError from bs4 import BeautifulSoup def getTitle(url): try: html = urlopen(url) except HTTPError as e: return None try: bsObj = BeautifulSoup(html.read()) title = bsObj.body.h1 except AttributeError as e: return None return title title = getTitle("http://www.pythonscraping.com/pages/page1.html") if title == None: print("Title could not be found") else: print(title)定义了一个getTitle方法来获取网页的标题,其中有简单的处理异常机制。在网页爬虫的编写过程中,异常是非常常见的,所以需要处理异常。简单的总结本章的爬虫,第一步urlopen一个网页,然后将这个网页的内容(. read())转化成BeautifulSoup对象,从而提取该对象中的各种标签内容。
第二章 HTML网页解析
BeautifulSoup包中有两个重要的方法:find()(找第一个)和findAll()(找所有)。它们可以有很多参数,但是绝大多数情况下只需要使用两个就行了。
find(tag,attributes)和 findAll(tag,attributes)
例如
nameList = bsObj.findAll("span", {"class":"green"}) nameList = bsObj.find("span", {"class":"green"})即获得span标签下,属性class为green的内容。当然我们还可以同时获得class为red的内容,代码如下
nameList = bsObj.findAll("span", {"class":"green","class":"red"}) nameList = bsObj.find("span", {"class":"green","class":"red"})如果要获得各个tag下的某个属性内容,可以使用以下方法:
bsObj.findAll("", {"id":"text"})即把tag省略来代表所有tag。后面还可以对标签的兄弟姐妹进行操作。
除了BeautifulSoup对象,还有NavigableString对象和The Common对象比较重要,在这里不做细讲。
正则表达式此处略去,详情可参考本人另一篇博客《正则表达式入门(python)》。使用以下代码作为示例:
from urllib.request import urlopenfrom bs4 import BeautifulSoupimport re html = urlopen("http://www.pythonscraping.com/pages/page3.html") bsObj = BeautifulSoup(html) images = bsObj.findAll("img", {"src":re.compile("\.\.\/img\/gifts/img.*\.jpg")}) for image in images: print(image["src"])</span>示例表示的是找出网页中的所有图片路径。
第三章 开始爬取数据
以wiki中kevin Bacon 页面作为爬取对象,然后选取其中指向特定的网页再次爬取。示例如下
from urllib.request import urlopen from bs4 import BeautifulSoup import datetime import random import re random.seed(datetime.datetime.now())#随机种子 def getLinks(articleUrl): html = urlopen("http://en.wikipedia.org"+articleUrl) bsObj = BeautifulSoup(html) return bsObj.find("div", {"id":"bodyContent"}).findAll("a",href=re.compile("^(/wiki/)((?!:).)*$")) links = getLinks("/wiki/Kevin_Bacon") while len(links) > 0: newArticle = links[random.randint(0, len(links)-1)].attrs["href"]#随机选取一个网页爬取 print(newArticle) links = getLinks(newArticle)
利用scrapy爬取数据的方法暂时先不介绍。
第四章 使用API
本章主要讲了利用twitter和google的API爬取数据,但是利用API时也有很多限制,非我本意,故省略。小伙伴要是感兴趣可以自行查阅。
第五章 存储数据
本章主要讲述使用MYSQL数据库存取数据,其各种优点就不详述了,直接上干货。linux安装如下:
sudo apt-get install mysql-server
安装完成之后就可以连接mysql了,连接MYSQL:
格式: mysql -h主机地址 -u用户名 -p用户密码
连接本机:mysql -uroot -p123 (示例)
连接远程服务器:mysql -h 192.168.1.1 -uroot -p123(示例)
退出:exit或者quit
退出编辑:\c 或者 ;
mysql基本命令:
1.CREATE DATABASE scraping; 2.USE scraping; 3.CREATE TABLE pages; 4.CREATE TABLE pages (id BIGINT(7) NOT NULL AUTO_INCREMENT, title VARCHAR(200),content VARCHAR(10000), created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY(id)); 5.DESCRIBE pages; 6. INSERT INTO pages (title, content) VALUES ("Test page title", "This is some test page content. It can be up to 10,000 characters long."); 7.INSERT INTO pages (id, title, content, created) VALUES (3, "Test page title", "This is some test page content. It can be up to 10,000 characters long.", "2014-09-21 10:25:32"); 8.SELECT * FROM pages WHERE id = 2; 9.SELECT * FROM pages WHERE title LIKE "%test%"; 10.SELECT id, title FROM pages WHERE content LIKE "%page content%"; 11.DELETE FROM pages WHERE id = 1; 12.UPDATE pages SET title="A new title", content="Some new content" WHERE id=2; 13.DROP database aaa;#show databases;中是databases,多了s
下面分别对上述12条语句解释。
1. 创建数据库,名称为scraping
2. 使用数据库(选定)
3. 在选定的数据库中创建表 pages。提示出错,原因是创建表格时必须存在列,故正确方式如4.
4. 正确的创建表的方式,创建了4列
5.查看创建的表pages
6.插入title和content信息
7.也能自行插入id和created列,但是不建议,mysql自动管理主键id(每次加1)和时间
8.选择id=2的所有行
9.选择title中有test的所有行
10.选择content中有page content的id 和 title单元
11.删除id=1的所有行
12.更新id=2的相关信息
13. 删除aaa数据库
首先安装PyMySql包,如下
curl -L https://github.com/PyMySQL/PyMySQL/tarball/pymysql-0.6.2 | tar xz cd PyMySQL-PyMySQL-f953785/ python setup.py install完成之后即可用python调用mysql。在爬取数据的时候,可能会遇到编码问题,书中给了一个比较繁琐的方法,就是每次对每个表每项数据都重新设置。本文暂且不解决该问题,有机会重新探讨。下面给一个书中的示例
from urllib.request import urlopen from bs4 import BeautifulSoup import datetime import random import pymysql conn = pymysql.connect(host='127.0.0.1', unix_socket='/tmp/mysql.sock',user='root', passwd=None, db='mysql', charset='utf8')#创建一个连接 cur = conn.cursor()#创建一个游标,相当于一个对象,如果要对多个表进行操作可以创建多个对象 cur.execute("USE scraping")#对象.方法() 使用scraping表格 random.seed(datetime.datetime.now()) def store(title, content):#类似的使用对象.方法()来操作数据库 cur.execute("INSERT INTO pages (title, content) VALUES (\"%s\",\"%s\")", (title, content)) cur.connection.commit() def getLinks(articleUrl): #爬取数据 html = urlopen("http://en.wikipedia.org"+articleUrl) bsObj = BeautifulSoup(html) title = bsObj.find("h1").find("span").get_text() content = bsObj.find("div", {"id":"mw-content-text"}).find("p").get_text() store(title, content) return bsObj.find("div", {"id":"bodyContent"}).findAll("a",href=re.compile("^(/wiki/)((?!:).)*$")) links = getLinks("/wiki/Kevin_Bacon") try: while len(links) > 0: newArticle = links[random.randint(0, len(links)-1)].attrs["href"] print(newArticle) links = getLinks(newArticle) finally: cur.close()#使用完数据库操作后要及时关闭游标和连接,因为游标和连接不会自动关闭,这样能避免数据库出现问题 conn.close()当然避免过多的对数据库的访问,还能通过改善表格的设计来实现,这就需要大家参考数据库的相关知识了。设计好数据库后可以编写SQL语句来创建数据库,而不必在命令行中创建。
后续将继续阅读本书的内容,并及时更新博客。