python制作一个简单的豆瓣书单爬虫
运行环境
- python3
- request库
- BeautifulSoup
- re库(正则库) 点这里
- os库(文件操作)
预备知识
- python基础语法
- html(css)基础
认识python
Python 简介:
Python 是一种解释型语言: 这意味着开发过程中没有了编译这个环节。类似于PHP和Perl语言。
Python 是交互式语言: 这意味着,您可以在一个Python提示符,直接互动执行写你的程序
总而言之,python是一门非常非常容易上手的语言
学习python:
1 . python列表
序列(List[ ])是Python中最基本的数据结构。序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推。
Python有6个序列的内置类型,但最常见的是列表和元组。
序列都可以进行的操作包括索引,切片,加,乘,检查成员。
点这里
2 . while循环
Python While 循环语句
Python 编程中 while 语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务。其基本形式为:
while (count < 9):
print 'The count is:', count
count = count + 1
3 . for循环
Python for循环可以遍历任何序列的项目,如一个列表或者一个字符串。
for循环的语法格式如下:
for iterating_var in sequence:
statements(s)`
4 . 函数
定义一个函数
你可以定义一个由自己想要功能的函数,以下是简单的规则:
函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
函数内容以冒号起始,并且缩进。
return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None
def printme( str ):
"打印传入的字符串到标准显示设备上"
print str
return
要补充的是:
代码缩进很重要!
代码缩进很重要!
代码缩进很重要!
5 . 接下来自己看 = =
html--DOM:
每个网页都是由这类结构组成的,每个元素的构成稍作了解
BeautifulSoup
首先要解释下库的作用,我对库的理解就是一个封装好了的工具箱,大家可以非常方便的调用里面的函数,
bs4呢,就是一个可以让你非常方便的获取到文档中元素的具体位置的一个函数库>bs4官方文档
代码实现
爬取目标如下:豆瓣250
不和你多bb,终于到编写代码的阶段了,我们分布解析这个程序
-
导入库
import urllib.request import re import os from bs4 import BeautifulSoup
-
打开文件
fu=open('book.html','w') ##新建文件book.html fu.write('<html>\n') ##写入html格式 fu.write('<body>\n') fu.write('<p align="center">\n') fu.write("\t\t-------豆瓣最受欢迎图书Top150-------\n\n") fu.write("</p>\n") fu.write('<table>\n') print("正在爬取书单中.......\n\n\n")
-
爬取书单
while m<=125: L1=[] ##读者评价列表 L2=[] ##图书信息 L3=[] ##图书名称 L4=[] ##读者评分 url="https://book.douban.com/top250?start="+str(m) ##拼接页码参数 req = urllib.request.Request(url) page = urllib.request.urlopen(req) #链接网页 soup=BeautifulSoup(page,"html.parser") ##用python自带的htmlparser解析器读取网页,并用bs4进行解析 sentence=soup.find_all('span',class_="inq") ##获取读者评价 information=soup.find_all("p",class_="pl") ##获取图书信息 book=soup.findAll('a',attrs={"href":re.compile(r'https://book.douban.com/subject/.*/'),"title":re.compile(r'.*')}) ##图书名称 rate=soup.findAll('span',class_='rating_nums') ##读者评分 ##寻找参数 for i in sentence: L1.append(i.get_text()) ##添加到列表尾端 for j in information: L2.append(j.get_text()) for p in book: L3.append(p.get_text()+'$') temp=''.join(L3) ##列表转字符串 c=temp.replace('\n','').replace(' ','').rstrip('$').split('$') ##用replace去除空格等无用字符 for q in rate: L4.append(q.get_text()) b=zip(c,L4,L2,L1) #列表用zip方法 交叉合并 ##对参数格式化处理 n=list(b) for s in n: print('正在爬取第',e,'条数据') o='<img src=D:\pic\\'+str(e)+'.jpg>' fu.write('<tr>\n') fu.write('<td>%s\n%d%s%s</td>\n'%(o,e,'.',s[0]))##mz fu.write('<td>%s</td>\n'%s[1]) fu.write('<td>%s</td>\n'%s[2]) fu.write('<td>%s</td>\n'%s[3]) fu.write('</tr>\n')##写进网页 e+=1 m+=25 ##翻页,循环爬取网页
-
下载书籍封面:
def download():##下载图片 g=0 ##书本数目,换页用 v=1 ##次数 try: os.mkdir('D:\pic') ##创建文件夹 except: pass os.chdir('D:\pic') print("正在下载图片中....\n\n\n") while g<=125: url="https://book.douban.com/top250?start="+str(g) ##获取不同页面的书本信息 page=urllib.request.urlopen(url) ##链接网页 html=page.read().decode('utf-8') ##中文编码处理 p=r'src="(.*\.jpg)"' imglist=re.findall(p,html) ##获取图片 for each in imglist: print(each) urllib.request.urlretrieve(each,str(v)+'.jpg',None) ##下载图片 v+=1 g+=25 ##翻页,循环爬取网页
总体代码:
import urllib.request import re import os from bs4 import BeautifulSoup def fun():##爬取信息 try: m=0 ##书本数目,换页用 e=1 ##爬取次数 fu=open('book.html','w') fu.write('<html>\n') fu.write('<body>\n') fu.write('<p align="center">\n') fu.write("\t\t-------豆瓣最受欢迎图书Top150-------\n\n") fu.write("</p>\n") fu.write('<table>\n') print("正在爬取书单中.......\n\n\n") while m<=125: L1=[] ##读者评价列表 L2=[] ##图书信息 L3=[] ##图书名称 L4=[] ##读者评分 url="https://book.douban.com/top250?start="+str(m) req = urllib.request.Request(url) page = urllib.request.urlopen(req) soup=BeautifulSoup(page,"html.parser") ##用python自带的htmlparser解析器读取网页 sentence=soup.find_all('span',class_="inq")##读者评价 information=soup.find_all("p",class_="pl")##图书信息 book=soup.findAll('a',attrs={"href":re.compile(r'https://book.douban.com/subject/.*/'),"title":re.compile(r'.*')})##图书名称 rate=soup.findAll('span',class_='rating_nums')##读者评分 for i in sentence: L1.append(i.get_text()) for j in information: L2.append(j.get_text()) for p in book: L3.append(p.get_text()+'$') temp=''.join(L3) c=temp.replace('\n','').replace(' ','').rstrip('$').split('$') # y=x.replace(' ','') # z=y.rstrip('$') ##删除字符串最右边 # c=z.split('$') ##格式处理,返回字符串列表 for q in rate: L4.append(q.get_text()) b=zip(c,L4,L2,L1)#列表用zip方法 交叉合并 n=list(b) for s in n: print('正在爬取第',e,'条数据') o='<img src=D:\pic\\'+str(e)+'.jpg>' fu.write('<tr>\n') fu.write('<td>%s\n%d%s%s</td>\n'%(o,e,'.',s[0]))##mz fu.write('<td>%s</td>\n'%s[1]) fu.write('<td>%s</td>\n'%s[2]) fu.write('<td>%s</td>\n'%s[3]) fu.write('</tr>\n')##写进网页 e+=1 m+=25 fu.write('</table>\n') fu.write('</body>\n') fu.write('</html>\n') fu.close() print('爬取完成!请去D盘pic文件夹查看本地网页!') except: print("输出文件失败!") def download():##下载图片 g=0 ##书本数目,换页用 v=1 ##次数 try: os.mkdir('D:\pic') ##创建文件夹 except: pass os.chdir('D:\pic') print("正在下载图片中....\n\n\n") while g<=125: url="https://book.douban.com/top250?start="+str(g) ##获取不同页面的书本信息 page=urllib.request.urlopen(url) html=page.read().decode('utf-8') ##中文编码处理 p=r'src="(.*\.jpg)"' imglist=re.findall(p,html) for each in imglist: print(each) urllib.request.urlretrieve(each,str(v)+'.jpg',None) ##下载图片 v+=1 g+=25 ##主体程序 download() fun()
-
运行:
download() fun()
效果:
总结
以上