Python爬虫爬取基础网页信息

Ps:本文是关于Py爬虫的基础使用,若网站侵权请邮箱联系删除。

准备工具

  • Python3
  • BeautifulSoup包

分析网页

233网校会定期推送一些二级考试题目,属于纯文本型。


我们使用网页查看器来查看网页结构,可以看到题目和每个选项以及答案的分布

我们可以看到他们在 class="newsArea-2nd-PageWord" 的 div 下,并且我们可以观察到这些网址的顺序特征

http://www.233.com/ncre2/Office/moniti/ http://www.233.com/ncre2/Office/moniti/index02.html http://www.233.com/ncre2/Office/moniti/index03.html ...

并且我们可以看到这些网址又属于哪些块下,稍后我们将提取它们

我们先来考虑一个页面的数据提取:

1
2
3
4
req = urllib.request.Request(url=url, headers=headers)
res = urllib.request.urlopen(req)
res.encoding = 'utf-8'
data = res.read()

以上是请求方式和返回数据的获取,需要导入 import urllib.request ,并且注意将 response 的编码格式设置为utf-8,以保证中文信息的正确显示。最后将返回内容提取到一个变量中,即 res.read()
但是当你此刻打印 data 时候,会发现data中存储的是整个页面的内容,此时我们就要用到 BeautifulSoup 来解析内容了。

Parser 方法 优点 缺点
Python’s html.parser BeautifulSoup(markup,”html.parser”) python自身带有
速度比较快
不能很好地兼容(Python 2.7.3 or 3.2.2之前)
lxml’s HTML parser BeautifulSoup(markup,”lxml”) 速度很快
兼容性好
lxml只会局部遍历
html5lib BeautifulSoup(markup, “html5lib”) 兼容性很好
可以像web浏览器一样解析html页面
Creates valid HTML5
速度很慢

这里我们选择Python’s html.parser就足够了。当然我们要先from bs4 import BeautifulSoup

接着我们就是要在一个链接列表页面获取到每个链接,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
lista = []
lista = soup.select('ul.fl.f14.list-box.best-list.mt10 li a')
```
这里有些坑坑,当一个 class 样式的名字中包含空格时,比如此处**class="tip-box content bgf9 mt20 "**,我们使用 soup 解析时候就要将空格替换为点,紧接着用空格隔开他的子级标签。即可获取到当前标签下的内容。当然 我们是用数组存放的。
同理,我们将获取到的这些链接再用一个数组存放起来:
```Python
urls = []
for li in lista:
urls.append(li['href'])
```
取出li中的每个href,并存放
紧接着便是对每个链接进行请求,并从返回的html中解析出我们需要的内容:
```Python
for r in urls:
req = urllib.request.Request(url=r, headers=headers)
res = urllib.request.urlopen(req)
data = res.read()
soup = BeautifulSoup(data, "html.parser")
name = soup.select('h2')
listp = []
listp = soup.select('.newsArea-2nd-PageWord p')
if (name[0].text == "网校课程" or len(name) == 0):
name = soup.select('.news-con-blk h1')
listp = soup.select('.news-body p')
sdata = []
for p in listp:
sdata.append(p.text)
s = '\n'.join(sdata)
saveFile(s, name[0].text)
print(name[0].text + "保存成功")
time.sleep(1)
```
这里我们需要自己再去分析网页结构了,我这里中间还加了部分判断内容,是因为在爬虫运行到第9个网站时候,它的网页结构发生了变化,题目都存在了与之前不同的标签中标签中。我们爬取数据自然是要存在文件中,最常用的一是写入数据库,二就是存入文件,写入数据库没什么好有歧义的,sql语句拼接就好。存入文件也十分简单:
```Python
def saveFile(data, name):
path = "E:\\sxks\\JavaProblems\\" + name + ".txt"
print(path)
data = data.encode('utf-8')
f = open(path, 'wb+')
f.write(data)
f.close()
```
这里我直接讲将链接的题目作为文件名存储了。对单个链接页面的处理就结束了,我们想要爬取多个页面的自然只是获取了链接存入数组遍历即可。
# 重要的说在这里
差点漏了一点,那就是在请求的时候,我们需要伪造请求头,即我们需要将自己伪装成一个浏览器,否则在对大多网站请求的时候,很容易就会被识破。这里只需要定义
```Python
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
req = urllib.request.Request(url=url, headers=headers)

请求时候使用即可。

另外一点可说的就是,最好在请求时候适当的使用time.sleep(1),使请求不是那么频繁,不易被察觉。

完整源码Github