import requests #requests模块用于HTTP请求
import codecs #codecs模块用于文件操作
from bs4 import BeautifulSoup #beautifulSoup库用于对html代码进行解析
#要爬取的地址
URL="https://book.douban.com/top250"
#user-agent,模仿浏览器,防止被目标网站反爬
HEADERS = {
"User-Agent":"Mozilla/5.0(Macintosh; Intel Mac OS X 10_11_2 ) AppleWebKit/537.36(KHTML, like Gecko) Chrome/60.0.3202.62 Safari/537.36"
}
#定义请求特定URL页面的方法,用于多次请求
def download_page(url):
#请求页面,获取要爬取的页面内容
data = requests.get(url,headers=HEADERS).content
return data
#从请求回来的特定页面中筛选出来我们需要的特定的信息
def parse_html(html):
#使用bs解析获取的页面,测试是否可以用print(soup.pretiffy())打印查看获取的页面
soup = BeautifulSoup(html,'html.parser')
#print(html)
#print(soup.prettify())
#exit()
#利用BeautifulSoup获取要爬取的页面信息
#查找页面中class为indent的div(首先要从页面分析出来哪个条件可以唯一定位书籍内容的div)
book_list_soup = soup.find('div',attrs={'class':'indent'})
# print(book_list_soup)
# exit()
#定义一个数组用来存储书名信息
book_name_list=[]
#遍历书籍div内的信息,找到每个table元素来进行后续操作
for book_li in book_list_soup.find_all('table'):
# print(book_li)
# exit()
#对每个table元素应用以下筛选逻辑
#找到图书描述的div
detail = book_li.find('div',attrs={'class':'pl2'})
#找到图书的名字所在标签,利用字符串操作得到纯粹的书名
book_name=detail.find('a').getText().replace('\t','').replace('\n','').replace(' ','')
#把书名添加到数组中
book_name_list.append(book_name) #添加到list中
# print(book_name_list)
# exit()
#遍历完当前页面的书籍后,找到下一页的链接继续上面的流程来爬取书名
next_page = soup.find('span',attrs={'class':'next'}).find('a')
#如果有下一页,则拼接下一页的url,继续爬取,同时返回图书名称的list
if next_page:
return book_name_list,next_page['href']
#如果没有则爬虫结束,同时返回图书名称的list
return book_name_list,None
def main():
#局部变量url,用于记录每次爬取的页面的URL
url=URL
#循环变量,用于控制台显示页数
i = 1
#打开文件,使用utf-8编码
with codecs.open('books.txt','wb',encoding='utf-8') as fp:
while url:
print('正在获取页数: '+str(i))
i=i+1
#调用获取页面的函数
html = download_page(url)
#调用过滤页面信息以得到书名的函数
books,url=parse_html(html)
#将获取的书名写入文件,利用format函数格式化书名列表
fp.write(u'{books}'.format(books='\r\n'.join(books)))
#当页面直接运行时,执行main函数
if __name__=='__main__':
main()