爬虫Day9-requests实战

前言

之前介绍requests 这个库的时候在文尾说过要做一篇实战的文章,今天突然想起,然后就写一下咯。

爬虫Day5-requests介绍

今天的主题是——使用 requests请求库 和 re 解析库进行爬取当当网热门top 500书籍。

url = http://bang.dangdang.com/books/fivestars/01.00.00.00.00.00-recent30-0-0-1-1


网页省察

第一步:我们进入url 链接之后,按F12进入开发者模式

  • 总结出以下规律:所有书籍都存放在一个 ul 标签下面
  • 每一本书都是 一个li 节点

第二步:切换页码数,观察 url 变化

  • 发现 url 链接最后面的数字发生改变—— 由”1“ 变成 ”2“,这正好对应上我们翻页的页码数
  • 每一页的书籍量为20 , Top 500 的书籍 爬取 25 个连接就可以爬取完毕


动手写代码

1
2
3
4
5
6
7
8
def get_page(page):
kv = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36'
} # 伪装浏览器标识
url = 'http://bang.dangdang.com/books/fivestars/01.00.00.00.00.00-recent30-0-0-1-' + str(page)
# 由 变量 page 来进行控制翻页
response = requests.get(url=url, headers=kv) # 发出请求
return response.text # 将响应内容返回

解析

我们点开的每一个 li 节点,观察我们需要爬取的节点信息

  • 发现每一段信息都有一个div 存储着,我们只需要re 正则匹配出来,就欧克了

解析代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def parser_page(html):
regix = re.compile(r'<li.*?list_num.*?">(\d+).*?<img src="(.*?)".*?class="name".*?title="(.*?)">.*?class="tuijian">(.*?)</span>.*?class="publisher_info.*?title="(.*?)".*?class="biaosheng".*?<span>(.*?)</span>.*?class="price_n">&yen;(.*?)</span>',re.S)
# 编写匹配规则
doc = regix.findall(html)
for i in doc:
yield {
'排名':i[0],
'图片':i[1],
'书名':i[2],
'推荐指数':i[3],
'作者':i[4],
'五星好评人数':i[5],
'价格':i[6]
} # 将内容变成一个生成器
return doc

我们先看看 这个 叫 “doc” 生成器 的内容,使用 for 循环遍历出来:

perfect! 这样我们就把信息完美的抓取下来了。



写入文件

接下来,我们就将内容写入文件,以便后期的数据分析。

1
2
3
4
with open("book.txt","w",encoding="utf-8") as f:
for writeline in doc:
print(writeline)
f.write(str(writeline) + '\n')

我们运行一下代码,效果如下:



爬虫完善

最后,我们需要控制爬取速率,做一个有素质的爬虫,毕竟一直爬取别人网站,服务器也会受不了的呀。并且,加上异常处理,一个简单的小爬虫就写好了。

完整代码如下:

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
import requests
import time
import re


def get_page(page):
kv = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36'
}
url = 'http://bang.dangdang.com/books/fivestars/01.00.00.00.00.00-recent30-0-0-1-' + str(page)
response = requests.get(url=url, headers=kv)
return response.text


def parser_page(html):
regix = re.compile(r'<li.*?list_num.*?">(\d+).*?<img src="(.*?)".*?class="name".*?title="(.*?)">.*?class="tuijian">(.*?)</span>.*?class="publisher_info.*?title="(.*?)".*?class="biaosheng".*?<span>(.*?)</span>.*?class="price_n">&yen;(.*?)</span>',re.S)
doc = regix.findall(html)
for i in doc:
yield {
'排名':i[0],
'图片':i[1],
'书名':i[2],
'推荐指数':i[3],
'作者':i[4],
'五星好评人数':i[5],
'价格':i[6]
}
return doc


def main():
for i in range(1,26):
html = get_page(i)
doc = parser_page(html)
time.sleep(4)
with open("book.txt","w",encoding="utf-8") as f:
for writeline in doc:
print(writeline)
f.write(str(writeline) + '\n')


if __name__ == '__main__':
main()


后记

可以发现,使用 re 来解析库的难度还是有的,不过,我想说的是,使用什么模块并不重要,只有最适合当前需求的模块,取决于你如何去灵活运用它,编程语言也是这样。