前言
网络爬虫程序的核心任务就是获取网络上的数据,并对特定的数据做一些处理。因此,如何“采集 ”所需的数据往往成为爬虫成功与否的重点。数据采集最常见的任务就是从网页中抽取数据,一般所说的“抓取”就是指这个动作。抓取工具有:正则表达式(即python的正则表达式库——re模块)、Xpath、BeautifulSoup模块及lxml模块。
本文采取BeautifulSoup模块来进行抓取定位。
任务
从豆瓣读书网站爬取小说标签下的书名、作者、评分信息。
一、导入相关包
import requests
from bs4 import BeautifulSoup
import csv #文件写入需要
二、爬取第一页的内容
首先我们先尝试爬取第一页的数据,url=‘https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T’
##要抓取的数据的网址
url = 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T'
#发出请求,得到一个resp响应,(需要去抓取工具那查看一下地址栏里的链接是不是get方式提交)
page_text = requests.get(url=url, headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36'})
#解析数据
#1、把页面源代码交给BeautifulSoup进行处理,生成bs对象
soup = BeautifulSoup(page_text.text, "html.parser") #指定html解析器
#2、从bs对象中查找定位我们需要的数据(书名、作者、评分),用以下两个函数,这里需要对html文档的标签有所了解
#html的语法 : <标签 属性="属性值"> 被标记的内容 </标签>
# find(标签,属性=值)
# find_all(标签,属性=值)
title = soup.find_all("h2") #这里表示我们要抓取的文章名称是属于标签<h2>的
autor = soup.find_all("div", class_="pub") #这里表示作者信息属于标签<div> 且属性值为class:"pub", 这里写class_是因为要与class区别开了。
score = soup.find_all("span",class_="rating_nums") #同上解释
#3、将数据一一对应取出来写进文件里
file = open('豆瓣小说综合排序目录.csv', mode='a', encoding='utf-8-sig', newline='')
# mode指定文件写入方式为a,表示数据追加,newline消除空行
csv_write = csv.DictWriter(file, fieldnames=['title', 'autor', 'score'])
csv_write.writeheader() #写入一次表头数据
for x , y ,z in zip(title, autor, score):
title1 = x.get_text().strip("\n /") #strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列
autor1 = y.get_text().strip("\n /")
score1 = z.get_text().strip("\n /")
data_dict = {'title':title1, 'autor':autor1, 'score':score1}
csv_write.writerow(data_dict) #将数据写入文件中
爬取的结果如下:
三、循环爬取多页
可以指定start参数来获取多页的信息
第一页:https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T
第二页:https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=20&type=T
第三页:https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=40&type=T
……
第379页:https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=7560&type=T
可以看出每页有20条数据,因此可以写进一个循环中
##尝试循环两页,看一下是否有错
for i in range(0,2):
url = 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start={}&type=T'.format(i*20)
完整代码
import requests
from bs4 import BeautifulSoup
import csv
file = open('豆瓣小说综合排序目录1.csv', mode='a', encoding='utf-8-sig', newline='')
csv_write = csv.DictWriter(file, fieldnames=['title', 'autor', 'score'])
csv_write.writeheader()
for i in range(0,2):
url = 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start={}&type=T'.format(i*20)
page_text = requests.get(url=url, headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36'})
soup = BeautifulSoup(page_text.text, "html.parser")
title = soup.find_all("h2")
autor = soup.find_all("div", class_="pub")
score = soup.find_all("span",class_="rating_nums")
for x , y ,z in zip(title, autor, score):
title1 = x.get_text().strip("\n /")
autor1 = y.get_text().strip("\n /")
score1 = z.get_text().strip("\n /")
data_dict = {'title':title1, 'autor':autor1, 'score':score1}
csv_write.writerow(data_dict)