python 网络数据采集(1-5章)

时间:2022-12-14 07:30:40

本文是《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语句来创建数据库,而不必在命令行中创建。

         


后续将继续阅读本书的内容,并及时更新博客。