本文主要介绍了对豆瓣读书top250的数据爬取与数据预处理,主要运用的库是re,request,Beautifulsoup,lxml。本文侧重于总结我在爬虫时遇到的一些坑,以及我对待这些坑的方法。文末附上了爬取的代码与数据。这是我的第一个爬虫实战:豆瓣电影top250的姊妹版。
在下载网页的时候,经常会遇到报错的情况。为了减少不必要的报错,下载的时候可以注意以下三点:
# 引入库
import re
import pandas as pd
import time
import urllib.request
from lxml.html import fromstring
from bs4 import BeautifulSoup
# 下载链接
def download(url):
print('Downloading:', url)
request = urllib.request.Request(url)
request.add_header('User-agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36') #进行伪装
resp = urllib.request.urlopen(request)
html = resp.read().decode('utf-8') #utf-8编码
time.sleep(3) #间隔3s,防止被封禁
return html
我在爬取豆瓣电影时,采用的方式是,下载每一个索引页,然后再下载每个索引页上的全部电影内容。总共有10个索引页,每页上有25个电影信息,这样就要下载 25*10+10=260 个网站。这样做固然可以增加些许的爬取信息,但是很明显的一个弊端就是耗时较久。
而我在爬取豆瓣读书时,采用的方式是,下载每一个索引页,然后直接提取索引页上的书籍信息(在书名下面)。这样仅需下载10个网页!而且,当我按爬豆瓣电影的老方法,爬取豆瓣读书时,我发现自己很难定位到作者这个信息。这启示我们要灵活选择爬取内容的方式。
第一篇豆瓣电影中提到过爬虫定位有三种方法:
那么具体该用那种方法呢?我的原则是:简单为上
我个人建议首选Xpath,因为最简单无脑,直接按 F12,然后选中要爬取的内容,右键copy xpath,其次可以使用Beautifulsoup中的find函数定位,不到万不得已,尽量不用正则表达式。
例如读取书名时采用xpath的定位方法,不过这里有两点要注意:
# 待爬取内容
name = []
rate = []
info = []
# 循环爬取每页内容
for k in range(10):
url = download('https://book.douban.com/top250?start={}'.format(k*25))
tree = fromstring(url)
soup = BeautifulSoup(url)
#找出该页所有书籍信息
for k in range(25):
name.append(tree.xpath('//*[@id="content"]/div/div[1]/div/table[{}]/tr/td[2]/div[1]/a/text()'.format(k+1))[0].strip())
rate.append(soup.find_all('span',{
'class':'rating_nums'})[k].get_text())
info.append(soup.find_all('p',{
'class':'pl'})[k].get_text())
# 拼接
book_data = pd.concat([name_pd, rate_pd, info_pd], axis=1)
book_data.columns=['书名', '评分', '信息']
book_data.head()
接下来将以上读取到的数据进行预处理:
需要注意的是 作家,出版社,出版年,定价 是按位置索引找出来的,但是这里存在两个异常数据,需要自己手动调整:
具体代码如下:
# 数据预处理:
# 将信息分割
Info = book_data['信息'].apply(lambda x: x.split('/'))
# 提取信息
book_data['作家'] = Info.apply(lambda x: x[0])
book_data['出版社'] = Info.apply(lambda x: x[-3])
book_data['出版年'] = Info.apply(lambda x: x[-2])
book_data['定价'] = Info.apply(lambda x: x[-1])
# 手动调整
book_data.iloc[9,4] = '群众出版社'
book_data.iloc[9,5] = '1981'
book_data.iloc[184,5] = '1996'
book_data.iloc[184,6] = '0'
#提取年份
f = lambda x: re.search('[0-9]{4,4}', x).group()
book_data['出版年'] = book_data['出版年'].apply(f)
#提取定价
g = lambda x: re.search('([0-9]+\.[0-9]+|[0-9]+)', x).group()
book_data['定价'] = book_data['定价'].apply(g)
book_data = book_data.drop(['信息'], axis =1)
# 输出
outputpath='c:/Users/zxw/Desktop/修身/与自己/数据分析/数据分析/爬虫/豆瓣读书/book.csv' ## 路径需要自己改!
book_data.to_csv(outputpath,sep=',',index=False,header=True,encoding='utf_8_sig')
目前自己对爬虫算是初步了解了,接下来可能会考虑学习 机器学习 的内容,先从 An Introduction to Statistical Learning with R 写起吧
代码及数据集(提取码: disq)