任意一图书类别的书籍信息数据
参考网址:豆瓣读书网
爬虫逻辑:【分页网页url采集】-【数据信息网页url采集】-【数据采集】
针对爬虫逻辑的三步走,采用函数式编程的方式进行数据爬取
函数1: get_urls(n) → 【分页网页url采集】
n:页数参数
结果:得到一个分页网页的list
函数2:get_dataurls(ui,d_h,d_c) → 【数据信息网页url采集】
ui:分页网址
d_h:user-agent信息
d_c:cookies信息
结果:得到一个数据信息网页的list
函数3:get_data(ui,d_h,d_c) → 【数据采集】
ui:数据信息网页
d_h:user-agent信息
d_c:cookies信息
结果:得到数据的list,每条数据用dict存储
采集字段
总共分为四个部分,其中②整体采集下来
设置登录信息cookies
写多了就会背了,标准的处理方式
cookies_lst = cookies.split("; ")
dic_cookies = {}
for i in cookies_lst:
dic_cookies[i.split("=")[0]] = i.split("=")[1]
注意:使用异常处理(try…except…)
要求采集200条数据,结果保存为dataframe,并做基本数据清洗
10页【分页网页url采集】- 每页20条数据
评分 字段
页数 字段
评价数量 字段
实战操作
步骤一、前期准备
import requests
from bs4 import BeautifulSoup
import pandas as
导入相关的库
步骤二、分析url
u2 = 'https://book.douban.com/tag/%E7%94%B5%E5%BD%B1?start=20&type=T'
u3 = 'https://book.douban.com/tag/%E7%94%B5%E5%BD%B1?start=40&type=T'
for i in range(10):
print("https://book.douban.com/tag/%E7%94%B5%E5%BD%B1?start={}&type=T".format(i*20))
输出结果为:(时间是2020年2月7日,下面每个url都可以正常打开)
https://book.douban.com/tag/%E7%94%B5%E5%BD%B1?start=0&type=T
https://book.douban.com/tag/%E7%94%B5%E5%BD%B1?start=20&type=T
https://book.douban.com/tag/%E7%94%B5%E5%BD%B1?start=40&type=T
https://book.douban.com/tag/%E7%94%B5%E5%BD%B1?start=60&type=T
https://book.douban.com/tag/%E7%94%B5%E5%BD%B1?start=80&type=T
https://book.douban.com/tag/%E7%94%B5%E5%BD%B1?start=100&type=T
https://book.douban.com/tag/%E7%94%B5%E5%BD%B1?start=120&type=T
https://book.douban.com/tag/%E7%94%B5%E5%BD%B1?start=140&type=T
https://book.douban.com/tag/%E7%94%B5%E5%BD%B1?start=160&type=T
https://book.douban.com/tag/%E7%94%B5%E5%BD%B1?start=180&type=T
步骤三、封装第一个函数
def get_url(n):
'''
【分页网址url采集】函数
n:页数参数
结果:得到一个分页网页的list
'''
lst = []
for i in range(10):
ui = "https://book.douban.com/tag/%E7%94%B5%E5%BD%B1?start={}&type=T".format(i*20)
#print(ui)
lst.append(ui)
return
步骤四、网页标签解析
注意: heders和cookies请根据自己的浏览器中显示的信息进行填写
首先进行试错,选取第一个页面的url,设置好请求头和cookies信息后,输出返回的访问状态情况
urllst = get_url(10)
u1 = urllst[0]
dic_heders = { 'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}
dic_cookies = {}
cookies = 'll="108296"; bid=b9z-Z1JF8wQ; _vwo_uuid_v2=DDF408830197B90007427EFEAB67DF985|b500ed9e7e3b5f6efec01c709b7000c3; douban-fav-remind=1; __yadk_uid=2D7qqvQghjfgVOD0jdPUlybUNa2MBZbz; gr_user_id=5943e535-83de-4105-b840-65b7a0cc92e1; dbcl2="150296873:VHh1cXhumGU"; push_noty_num=0; push_doumail_num=0; __utmv=30149280.15029; __gads=ID=dcc053bfe97d2b3c:T=1579101910:S=ALNI_Ma5JEn6w7PLu-iTttZOFRZbG4sHCw; ct=y; Hm_lvt_cfafef0aa0076ffb1a7838fd772f844d=1579102240; __utmz=81379588.1579138975.5.5.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; __utmz=30149280.1579162528.9.8.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; ck=csBn; _pk_ref.100001.3ac3=%5B%22%22%2C%22%22%2C1581081161%2C%22https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DNq2xYeTOYsYNs1a4LeFRmxqwD_0zDOBN253fDrX-5wRdwrQqUpYGFSmifESD4TLN%26wd%3D%26eqid%3De7868ab7001090b7000000035e1fbf95%22%5D; _pk_ses.100001.3ac3=*; __utma=30149280.195590675.1570957615.1581050101.1581081161.16; __utmc=30149280; __utma=81379588.834351582.1571800818.1581050101.1581081161.12; __utmc=81379588; ap_v=0,6.0; gr_session_id_22c937bbd8ebd703f2d8e9445f7dfd03=b6a046c7-15eb-4e77-bc26-3a7af29e68b1; gr_cs1_b6a046c7-15eb-4e77-bc26-3a7af29e68b1=user_id%3A1; gr_session_id_22c937bbd8ebd703f2d8e9445f7dfd03_b6a046c7-15eb-4e77-bc26-3a7af29e68b1=true; _pk_id.100001.3ac3=6ec264aefc5132a2.1571800818.12.1581082472.1581050101.; __utmb=30149280.7.10.1581081161; __utmb=81379588.7.10.1581081161'
cookies_lst = cookies.split("; ")
for i in cookies_lst:
dic_cookies[i.split("=")[0]] = i.split("=")[1]
ri = requests.get(u1, headers = dic_heders, cookies = dic_cookies)
print(ri)
输出结果为:<Response [200]>(允许访问)
接着就可以使用BeautifulSoup进行解析页面了,经过检查发现,所有的信息都在【ul class=subject-list】标签里面
选取第一个li标签进行试错
soup_i = BeautifulSoup(ri.text, 'lxml')
ul = soup_i.find('ul', class_ = 'subject-list')
lis = ul.find_all('li')
li0 = lis[0]
url_a = li0.find('a')['href']
print(url_a)
输出的结果为:https://book.douban.com/subject/34803201/
步骤五、封装第二个函数
def get_dataurls(ui,d_h,d_c):
'''
【数据信息网页url采集】
ui:分页网址
d_h:user-agent信息
d_c:cookies信息
结果:得到一个数据信息网页的list
'''
ri = requests.get(ui, headers = d_h, cookies = d_c)
soup_i = BeautifulSoup(ri.text, 'lxml')
ul = soup_i.find('ul', class_ = 'subject-list')
lis = ul.find_all('li')
lst = []
for li in lis:
lst.append(li.find("a")['href'])
return lst
print(get_dataurls(u1,dic_heders,dic_cookies))
输出的结果为:每个网址都可以打开(时间为2020年2月7号)
[‘https://book.douban.com/subject/34803201/’, ‘https://book.douban.com/subject/34866400/’,
‘https://book.douban.com/subject/34887412/’, ‘https://book.douban.com/subject/34922269/’,
‘https://book.douban.com/subject/25976544/’, ‘https://book.douban.com/subject/2326403/’, ‘https://book.douban.com/subject/1829226/’,
‘https://book.douban.com/subject/27174130/’, ‘https://book.douban.com/subject/27062726/’,
‘https://book.douban.com/subject/30317910/’, ‘https://book.douban.com/subject/34879912/’,
‘https://book.douban.com/subject/30304849/’, ‘https://book.douban.com/subject/30301599/’,
‘https://book.douban.com/subject/26435510/’, ‘https://book.douban.com/subject/34662082/’,
‘https://book.douban.com/subject/26848740/’, ‘https://book.douban.com/subject/30297417/’,
‘https://book.douban.com/subject/34320351/’, ‘https://book.douban.com/subject/1080370/’,
‘https://book.douban.com/subject/27600198/’]
步骤六、采集每页的数据
还是一样,在进行函数封装之前进行试错
urllst_1 = get_url(10)
urllst_2 = []
for u in urllst_1[:1]:
urllst_2.extend(get_dataurls(u,dic_heders,dic_cookies))
print("成功获取数据页面网址,成功采集{}条数据".format(len(urllst_2)))
输出结果为:成功获取数据页面网址,成功采集20条数据
由于这一部分已经调用了第二个函数,使用了requests请求,这时候就要使用try…except语句,防止系统报错而导致程序没有办法正常运行
urllst_1 = get_url(10)
urllst_2 = []
for u in urllst_1:
try:
urllst_2.extend(get_dataurls(u,dic_heders,dic_cookies))
print("成功获取数据页面网址,成功采集{}条数据".format(len(urllst_2)))
except:
print('数据信息网页获取失败,分页网址为:', u)
输出结果为:
获得每个电影信息的全部详尽的url之后,进行要求的四项数据的提取,还是一样,再进行循环提取之前,要进行试错,选取第一页的url,获取其中的四项数据
u2 = urllst_2[0]
ri = requests.get(u2, headers = dic_heders, cookies = dic_cookies)
print(ri)
输出结果为:状态码为200,可以正常访问
解析页面,分别找出四项数据对应的标签,然后提取里面的内容,注意这里对于获取的数据,建议是不要进行清洗的(如果是空行或者换行除外),比如下面输出的结果中有换行的话这个字符是可以处理的,但是比如评价人数里面含有“人评价”这种数据,建议在获取完之后统一处理。而不要在获取的时候进行处理
dic = {}
dic['书名'] = soup_i.find('div', id='wrapper').h1.text
dic['评分'] = soup_i.find('div', class_ = 'rating_self clearfix').strong.text
dic['评价人数'] = soup_i.find('a',class_ = 'rating_people' ).text
print(dic)
输出结果为:
关于要求二中要提取的内容比较复杂,查看源代码可以看出,几乎都是“散装”的,而且每个url下的显示的情况还不一样(②中的内容有多有少),如下
查看一下要求二中的格式化输出
infos = soup_i.find('div', id='info').text
print(infos)
输出的结果为:
去除空格后输出是这样子的
最后创建个字典将里面有用的信息全部录入进去,整理后要求二数据获取的全部代码如下
infos = soup_i.find('div', id='info').text.replace(" ","").split("\n")
dic ={}
for i in infos:
if ":" in i:
dic[i.split(':')[0]] = i.split(':')[1]
else:
continue
print(dic)
输出的结果为:
至此四项要求所要获取的数据全部获取成功了(关于要求二的全部内容的获取,在介绍完正则表达式后可以进行解决)
步骤七、封装第三个函数
def get_data(ui,d_h,d_c):
'''
【数据采集】
ui:数据信息网页
d_h:user-agent信息
d_c:cookies信息
结果:得到数据的list,每条数据用dict存储
'''
ri = requests.get(ui, headers = d_h, cookies = d_c)
soup_i = BeautifulSoup(ri.text, 'lxml')
dic = {}
dic['书名'] = soup_i.find('div', id='wrapper').h1.text
dic['评分'] = soup_i.find('div', class_ = 'rating_self clearfix').strong.text
dic['评价人数'] = soup_i.find('a',class_ = 'rating_people' ).text
infos = soup_i.find('div', id='info').text.replace(" ","").split("\n")
for i in infos:
if ":" in i:
dic[i.split(':')[0]] = i.split(':')[1]
else:
continue
return dic
u2 = urllst_2[0]
print(get_data(u2,dic_heders,dic_cookies))
用第一个url进行试错,输出结果如下
步骤八、将代码分开来写
代码分成两部分书写,通过下面代码进行分开
if __name__ == "__main__"
该段代码的意义是什么?
一个python的文件有两种使用的方法,第一是直接作为脚本执行,第二是import到其他的python脚本中被调用(模块重用)执行。因此该段代码的作用就是控制这两种情况执行代码的过程,在该行代码下的代码只有在第一种情况下(即文件作为脚本直接执行)才会被执行,而import到其他脚本中是不会被执行的
也就是该行代码前面就是导入的库和相关定义的函数,该行代码下面就是我们进行的具体赋值和对应的操作
全部代码如下
import requests
from bs4 import BeautifulSoup
import pandas as pd
def get_url(n):
'''
【分页网址url采集】函数
n:页数参数
结果:得到一个分页网页的list
'''
lst = []
for i in range(10):
ui = "https://book.douban.com/tag/%E7%94%B5%E5%BD%B1?start={}&type=T".format(i*20)
#print(ui)
lst.append(ui)
return lst
def get_dataurls(ui,d_h,d_c):
'''
【数据信息网页url采集】
ui:分页网址
d_h:user-agent信息
d_c:cookies信息
结果:得到一个数据信息网页的list
'''
ri = requests.get(ui, headers = d_h, cookies = d_c)
soup_i = BeautifulSoup(ri.text, 'lxml')
ul = soup_i.find('ul', class_ = 'subject-list')
lis = ul.find_all('li')
lst = []
for li in lis:
lst.append(li.find("a")['href'])
return lst
def get_data(ui,d_h,d_c):
'''
【数据采集】
ui:数据信息网页
d_h:user-agent信息
d_c:cookies信息
结果:得到数据的list,每条数据用dict存储
'''
ri = requests.get(ui, headers = d_h, cookies = d_c)
soup_i = BeautifulSoup(ri.text, 'lxml')
dic = {}
dic['书名'] = soup_i.find('div', id='wrapper').h1.text
dic['评分'] = soup_i.find('div', class_ = 'rating_self clearfix').strong.text
dic['评价人数'] = soup_i.find('a',class_ = 'rating_people' ).text
infos = soup_i.find('div', id='info').text.replace(" ","").split("\n")
for i in infos:
if ":" in i:
dic[i.split(':')[0]] = i.split(':')[1]
else:
continue
return dic
if __name__ == "__main__":
urllst_1 = get_url(10)
u1 = urllst_1[0]
dic_heders = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'
}
dic_cookies = {}
cookies = 'll="108296"; bid=b9z-Z1JF8wQ; _vwo_uuid_v2=DDF408830197B90007427EFEAB67DF985|b500ed9e7e3b5f6efec01c709b7000c3; douban-fav-remind=1; __yadk_uid=2D7qqvQghjfgVOD0jdPUlybUNa2MBZbz; gr_user_id=5943e535-83de-4105-b840-65b7a0cc92e1; dbcl2="150296873:VHh1cXhumGU"; push_noty_num=0; push_doumail_num=0; __utmv=30149280.15029; __gads=ID=dcc053bfe97d2b3c:T=1579101910:S=ALNI_Ma5JEn6w7PLu-iTttZOFRZbG4sHCw; ct=y; Hm_lvt_cfafef0aa0076ffb1a7838fd772f844d=1579102240; __utmz=81379588.1579138975.5.5.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; __utmz=30149280.1579162528.9.8.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; ck=csBn; _pk_ref.100001.3ac3=%5B%22%22%2C%22%22%2C1581081161%2C%22https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DNq2xYeTOYsYNs1a4LeFRmxqwD_0zDOBN253fDrX-5wRdwrQqUpYGFSmifESD4TLN%26wd%3D%26eqid%3De7868ab7001090b7000000035e1fbf95%22%5D; _pk_ses.100001.3ac3=*; __utma=30149280.195590675.1570957615.1581050101.1581081161.16; __utmc=30149280; __utma=81379588.834351582.1571800818.1581050101.1581081161.12; __utmc=81379588; ap_v=0,6.0; gr_session_id_22c937bbd8ebd703f2d8e9445f7dfd03=b6a046c7-15eb-4e77-bc26-3a7af29e68b1; gr_cs1_b6a046c7-15eb-4e77-bc26-3a7af29e68b1=user_id%3A1; gr_session_id_22c937bbd8ebd703f2d8e9445f7dfd03_b6a046c7-15eb-4e77-bc26-3a7af29e68b1=true; _pk_id.100001.3ac3=6ec264aefc5132a2.1571800818.12.1581082472.1581050101.; __utmb=30149280.7.10.1581081161; __utmb=81379588.7.10.1581081161'
cookies_lst = cookies.split("; ")
for i in cookies_lst:
dic_cookies[i.split("=")[0]] = i.split("=")[1]
urllst_2 = []
for u in urllst_1:
try:
urllst_2.extend(get_dataurls(u,dic_heders,dic_cookies))
print("成功获取数据页面网址,成功采集{}条数据".format(len(urllst_2)))
except:
print('数据信息网页获取失败,分页网址为:', u)
datalst = []
errorlst = []
for u in urllst_2[:20]:
try:
datalst.append(get_data(u, dic_heders, dic_cookies))
print("数据采集成功,总共采集{}条数据".format(len(datalst)))
except:
errorlst.append(u)
print("数据采集失败,失败网址为:",u)
df = pd.DataFrame(datalst)
df['评分'] = df['评分'].astype('float')
df['评价人数'] = df['评价人数'].str.split('人').str[0].astype('int')
df['页数'] = df['页数'].str.replace("页","").astype('float')
df.to_excel("豆瓣书籍数据.xlsx", index = False)
系统输出结果为:
豆瓣书籍数据.xlsx里面的内容如下: