Ea5ter's Bolg

python爬虫学习(一)

字数统计: 1.8k阅读时长: 7 min
2018/07/24 Share

0.00 引言

放假这两周实在有点浮躁,决定接下来是时间认真的学习一块知识。
之前对爬虫的认识就是一个在网络上收集信息的程序,感觉挺高山流水的。但当我知道谷歌在1994年成立时,就是两个斯坦福大学的毕业生加上一个陈旧的服务器和一个python爬虫的时候,才觉得爬虫其实就在我们的日常之中。
最近我找到了一本《python网络数据采集》,决定从这本书着手开始爬虫的学习。

1.00 环境准备

1.10 python环境

虽然这本书上用的是python3,但我装的是python2.7,不过影响不大。
关于python的安装网上已经有很多教程了,在这也不细述。

1.20 py编译器

工欲善其事必先利其器。一个好的好的编译器往往可以为我们节约大量的时间。笔者在这里强推pycharm!除了智能代码、代码高亮这些基本操作以外,这款编译器可以自动帮你安装第三方库!真的非常方便。
这款编译器的专业版是要收费的,不过免费的社区版就已经可以为我们解决大部分的问题。

2.00 来一碗BeautifulSoup

BeautifulSoup是python的一个第三方库,也是爬虫程序肯定会用到的库。我们安装这个库的最新版本BeautifulSoup4,直接在pycharm的第三方库搜”bs4”即可自动导入。下面来说下这个库的基本用法。

2.10 BeautifulSoup对象

使用BeautifulSoup库的BeautifulSoup对象即可把Html内容转化为方便处理的BeautifulSoup对象。
举个栗子,假如我们想爬取维基百科python词条下的标题”python”。先来分析网页源码:
看到标题”python”是在h1标签中的,那么我们用接下来的几行代码即可实现抓取:

1
2
3
4
5
6
7
8
9
10
import requests
from bs4 import BeautifulSoup
url = 'https://en.wikipedia.org/wiki/Python'
html = requests.get(url)
soup = BeautifulSoup(html.text, 'html.parser')

print(soup.h1)

# -------------打印效果如下-------------
<h1 class="firstHeading" id="firstHeading" lang="en">Python</h1>

可以看到这种方法是将h1标签的所有内容给打印出来的,如果只想得到标签的内容——“python”,可以使用get_text(),它会将标签给删除,留下最后的文字。
因为h1标签是被嵌套在body标签下的,所以使用soup.body.h1也可以达到相同的目的。是不是很简单?

2.20 find() & findAll()

这两个在爬虫最常用的函数,可以让我们更准确地找到我们想要的信息。
这两个函数要求我们传的参数其实都是差不多的:

1
2
findAll(trg, attributes, recursive, text, limit, keyword)
find(trg, attributes, recursive, text, keyword)

主要用的其实也就前两个,”trg”:标签名称,”attributes”:标签属性,这需要我们传一个字典。
举个栗子来演示其用法,我选择来爬中国第一弹幕网b站主页的东西,我们的目标是:

番剧的排行。我们将每个番剧的名字以及对于的链接爬取并打印出来。
分析源码:

发现每个链接和名字都是在class=”bangumi-rank-list rank-list”的”ul”标签下的”a”标签。接着写出代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
import requests
from bs4 import BeautifulSoup

# 1. BeautifulSoup初级使用
url = 'https://www.bilibili.com/'
html = requests.get(url)
soup = BeautifulSoup(html.text, 'html.parser')

trgs = soup.find("ul", {"class": "bangumi-rank-list rank-list"}).findAll("a", {"class": "ri-info-wrap"})
i = 1
for trg in trgs:
i += 1
print "No.%d :" %i + trg["title"] + " link=>" + trg["href"]

可运行结果居然报错了。

真是让人头皮发麻,接着我打开网页源代码,ctrl+f搜索”bangumi-rank-list rank-list”,居然也搜不到……
最后终于发现,这部分的代码是藏在JavaScript里面的,而这个方法探索不到js中的信息。终于真相了……还是回到我们熟悉的维基百科吧……

2.30 正则+BeautifulSoup

书上讲到这说了这么一个笑话:“如果你有一个问题打算用正则表达式来解决,那么就是两个问题了。”
哈哈哈~~好吧,其实我就想分享一下这个笑话而已。
其实学到后面正则表达式还真的挺有用的,不过这里不细述,毕竟这东西也说不清楚。举个栗子演示一下使用格式:find(“trg”, {“attributes”:re.compile(“你的正则表达式”)})

3.00 开始采集

这一块不难但挺有意思,主要记下代码。

3.10 采集整个网站

直接上代码吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# _*_ coding: utf-8 _*_
import requests
from bs4 import BeautifulSoup
import re

page = set()
def getlink(newurl):
global page
url = "https://en.wikipedia.org"
html = requests.get(url+newurl)
soup = BeautifulSoup(html.text, "html.parser")
for link in soup.find("div", {'id': 'bodyContent'}).findAll("a", {"href": re.compile('^(/wiki/)')}):
link = link['href']
if link not in page:
page.add(link)
print("-------------------\n"+link)
getlink(link)
getlink("")

有一点很有意思,就是这个page表。在方法内部定义了一个”global page”,一开始没明白什么意思,觉得直接把”page = set()”写在方法里面也可以呀。
但这个方法是递归的,要是直接写在方法里面,在下次递归时,又会重置这个”page”。所以必须用全局变量。真是学到了。最后用流程图理下整个过程:

3.20 维基百科六度分隔理论

这个就比较有意思啦!这个六度分隔理论简单来说:你最多通过六个人你就能够认识任何一个陌生人。那我岂不是就可以和给诺兰打电话啦!其实在社交网络这么发达的今天,我一个人就可以联系到他了……
那么如何在爬虫上实现这一理论呢?通过维基百科上的”Christopher Nolan”这一词条到任意一个词条到任意一个词条只需要不到6次跳转。真是让人跃跃欲试呀!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# _*_ coding: utf-8 _*_
import requests
from bs4 import BeautifulSoup
import re
import random
import datetime

page = set()
random.seed(datetime.datetime.now())
def getlink(articleurl):
html = requests.get("https://en.wikipedia.org"+articleurl)
soup = BeautifulSoup(html.text, "html.parser")
return soup.find("div", {'id':'bodyContent'}).findAll("a", {"href":re.compile('^(/wiki/)')})

links = getlink("/wiki/Christopher_Nolan")
i = 0
while len(links) > 0:
newArticle = links[random.randint(0, len(links)-1)]["href"]
i += 1
print "第 %d 个页面:" %i
print newArticle
if i == 6:
break
links = getlink(newArticle)

这里我们通过随机数从一个页面的词条连接中任意跳转,很显然我们没有实现到指定页面的跳转,但可以看下随机跳转六次会到什么地方。

我实在想象不出,诺兰和厨房水槽的新闻有什么关系。不过这确实很有意思。

4.00 结语

这几天的学习终于总结完了,其实写爬虫逻辑清晰是关键,经常会把爬的过程想的不够清晰,即使忽略一步都有可能到不了目的地。要学着画下流程图理思路,这真的很关键。

CATALOG
  1. 1. 0.00 引言
  2. 2. 1.00 环境准备
    1. 2.1. 1.10 python环境
    2. 2.2. 1.20 py编译器
  3. 3. 2.00 来一碗BeautifulSoup
    1. 3.1. 2.10 BeautifulSoup对象
    2. 3.2. 2.20 find() & findAll()
    3. 3.3. 2.30 正则+BeautifulSoup
  4. 4. 3.00 开始采集
    1. 4.1. 3.10 采集整个网站
    2. 4.2. 3.20 维基百科六度分隔理论
  5. 5. 4.00 结语