【python爬虫专项(24)】协调Selenium与requests+bs的方法

爬虫难点在哪里?

反爬问题 → 网页无法访问
页面动态信息(js脚本写入)→ 无法快速解析网页内容
页面信息js写入
网址非静态网址

selenium与requests+bs采集的异同是?

1)区别点
① 对于访问网址
selenium通过webdriver来实现,登陆则通过页面交互实现
requests实现,登陆通过设置cookies信息实现

② 对于解析网页信息
bs在解析网页标签的时候,是tag名称+属性来做定位,属于2个要素来定位
selenium则是通过1个要素定位,所以对于tag名称的需求并不是那么明显 → 掌握xpath
对于动态网页(js脚本写入),bs无法得到真实代码,selenium则可以 → 豆瓣搜索网页部分为例

2)相似点
数据采集都可以分为【网页访问】+【标签解析】
只要访问成功,页面数据采集都不是问题

未来如何搭配selenium与requests+bs?

同等情况下,requests+bs效率更高,但无法针对动态网址
搭配方案
存在【网页无法访问】与【页面动态信息】的情况下,优先用selenium解决,如果selenium和requests+bs都可以成功情况下,选择后者

实践操作:豆瓣搜索网页部分为例

案例网址:https://book.douban.com/subject_search?search_text=%E6%95%B0%E6%8D%AE&cat=1001 , 网页界面如下
在这里插入图片描述
分两部分采集
1) 1个页面获取15个书籍url链接,这里通过前10页来获取url → selenium,访问10次网址,得到150个dataurl
https://book.douban.com/subject_search?search_text=%E6%95%B0%E6%8D%AE&cat=1001
https://book.douban.com/subject_search?search_text=%E6%95%B0%E6%8D%AE&cat=1001&start=15
https://book.douban.com/subject_search?search_text=%E6%95%B0%E6%8D%AE&cat=1001&start=30
https://book.douban.com/subject_search?search_text=%E6%95%B0%E6%8D%AE&cat=1001&start=45
https://book.douban.com/subject_search?search_text=%E6%95%B0%E6%8D%AE&cat=1001&start=60

2) 每个书籍url链接的详细数据采集 → requests+bs,访问150次网址

步骤一、前期准备
from selenium import webdriver
import pymongo
import requests
from bs4 import BeautifulSoup
import re
import warnings
warnings.filterwarnings('ignore') 
    # 不发出警告

'''
1、获取书籍信息页面url
selenium
'''   
urllst = ['https://book.douban.com/subject_search?search_text=%E6%95%B0%E6%8D%AE&cat=1001',
'https://book.douban.com/subject_search?search_text=%E6%95%B0%E6%8D%AE&cat=1001&start=15',
'https://book.douban.com/subject_search?search_text=%E6%95%B0%E6%8D%AE&cat=1001&start=30',
'https://book.douban.com/subject_search?search_text=%E6%95%B0%E6%8D%AE&cat=1001&start=45',
'https://book.douban.com/subject_search?search_text=%E6%95%B0%E6%8D%AE&cat=1001&start=60']
    # 页面网址列表
brower = webdriver.Chrome()
    # 启动测试器

该部分实现相关库的导入,确定要爬取的网页网址及数量,以及启动浏览器窗口

步骤二、获取每本书的url

通过页面解析标签可知,所有的书籍内容都在【class=“item-root”】标签下面,每个数据对应的url都在【a】标签的属性【href】内部,如下
在这里插入图片描述
因此获取相应的信息,就可以通过下面的代码

dataurls = []
for url in urllst:
    brower.get(url)  
        # 访问网页
    divs = brower.find_elements_by_class_name('item-root')
        # 获取所有包括数据的div标签
    for div in divs:
        url = div.find_element_by_tag_name('a').get_attribute('href')
        dataurls.append(url)
        # dataurl存入list
        print('成功识别%i条数据网址'%len(dataurls))
print(dataurls)

运行以上的代码,输出结果如下:(这里应该是75条,第一条不是书籍的url,而是第一页的‘[丛书] 大数据技术与应用’的url)
在这里插入图片描述

获取每个url里面具体的信息

这里采用requests+bs获取具体的信息,第一个url需要过滤掉,代码如下

myclient = pymongo.MongoClient("mongodb://localhost:27017/")
db = myclient['豆瓣数据采集']
datatable = db['豆瓣搜索数据爬虫']

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 = 'bid=p-MBYcxHF9M; ap_v=0,6.0; gr_user_id=573d66a5-cf77-4a14-9799-8cab01e69fbc; gr_cs1_c99c8034-97a3-4160-8ed3-5490e97cdce2=user_id%3A0; _pk_ses.100001.3ac3=*; __utma=30149280.117671168.1581561701.1581561701.1581561701.1; __utmc=30149280; __utmz=30149280.1581561701.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmt_douban=1; __utma=81379588.989564917.1581561701.1581561701.1581561701.1; __utmc=81379588; __utmz=81379588.1581561701.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmt=1; _vwo_uuid_v2=D3B5A78721776CC769A182730BAA6A08D|bbbdd01c5303ea766f81b72ce3038247; __yadk_uid=AgS9pQmVaFeixgPeh4WILqM6HHzF52DK; dbcl2="150296873:ZizhwFVYPGw"; ck=t_44; gr_session_id_22c937bbd8ebd703f2d8e9445f7dfd03=1c48d36d-686f-4267-aa69-37d0bd910a4e; gr_cs1_1c48d36d-686f-4267-aa69-37d0bd910a4e=user_id%3A1; __utmb=81379588.2.10.1581561701; gr_session_id_22c937bbd8ebd703f2d8e9445f7dfd03_1c48d36d-686f-4267-aa69-37d0bd910a4e=true; push_noty_num=0; push_doumail_num=0; __utmv=30149280.15029; _pk_id.100001.3ac3=379e348ceaefb65f.1581561701.1.1581561716.1581561701.; __utmb=30149280.10.10.1581561701'
cookies_lst = cookies.split("; ")
for i in cookies_lst:
	dic_cookies[i.split("=")[0]] = i.split("=")[1]

n = 1
    # 设置数据库集合  
errorlst = []
for u in dataurls[1:]:
    try:
        ri = requests.get(url = u,headers =dic_heders, cookies = dic_cookies )
        soupi = BeautifulSoup(ri.text,'lxml')
            # 访问并解析网址
        dic = {}
        dic['书名'] = soupi.h1.text.replace('\n','')
        info1 = re.findall(r'[\d.]+',soupi.find('div',class_="rating_self clearfix").text)
        dic['评分'] = info1[0]
        dic['评价人数'] = info1[1]
            # 书名、评分、评价人数匹配
        info2 = soupi.find('div',id="info").text
        s1 = re.sub(r' +','',info2)
        lst = re.findall(r'\n.+:.+\n',s1)
        for i in lst:
            i = i.replace('\n','')
            dic[i.split(':')[0]] = i.split(':')[1]
            # 匹配简单字段
        zz = re.search(r'作者:([\s\S]+)\n出版社',s1)
        if zz:
            dic['作者'] = zz.group(1).replace('\n','')
            # 匹配作者信息,如果匹配成功则添加进字典
        yz = re.search(r'译者:([\s\S]+)\n出版年',s1)
        if yz:
            dic['译者'] = yz.group(1).replace('\n','')
            # 匹配译者信息,如果匹配成功则添加进字典
        dj = re.search(r'定价:\D*([.\d]+)\D*',s1)
        if dj:
            dic['定价'] = dj.group(1)
            # 匹配定价信息,如果匹配成功则添加进字典
        #datatable.insert_one(dic)  # 数据入库
        
        print('成功采集%i条数据'%n)
        n += 1
    except:
        print('网页采集失败,网址为:',u)
        errorlst.append(u)

输出的结果为:(上面插入数据库的这条代码,如果配置好数据库的话,记得放开注释)
在这里插入图片描述

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lys_828

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值