网络爬虫之豆瓣电影

网络爬虫常用方法

Python作为最易上手的编程语言之一,在很多领域的应用已经相对成熟,尤其是一些工具应用类的场景,比如本文要介绍的网络爬虫。网络爬虫目前比较成熟的方法有三种,在Python中都有现有打包好的包/库,直接调用,非常方便。本篇博客只关注网络爬虫的应用层面,重点放在如何解决实际问题,所以对三种方法的理论介绍不做过多描述。

  • BeautifulSoup
  • XPath
  • lxml

BeautifulSoup

Python中的一个HTML/XML的解析库,可以很方便地从网页中提取数据,自动将输入文档换成Unicode编码,输出文档转化成UTF-8编码。

导包

from bs4 import BeautifulSoup

转化本地文件

XXX = BeautifulSoup(open('本地文件'),'lxml')

转化网络文件

XXX = BeautifulSoup('字符串类型或者字节类型','lxml')

打印XXX对象显示出来的就是html文件中的内容

XPath

Python中一款高性能 HTML/XML 解析器,利用XPath可以快速定位特定元素,获取节点信息。

导包

from lxml import etree

解析语法方式1

XXX = etree.HTML('index.html')

解析语法方式2

XXX = etree.parse('index.html')

XPath通配符

通配符 描述
* 匹配任何元素节点
@* 匹配任何属性节点
node() 匹配任何类型的节点

lxml

也是Python中一个常用的 HTML/XML 解析器,可以跟XPath联合使用。

相关介绍参见XPath与lxml库介绍及爬虫案例

案例

之前在某厂实习,偶尔需要爬一下一些电影在豆瓣上的相关信息,通常这些电影的豆瓣ID都是已知的,就以这个为例吧。直接附上代码,思路比较清晰,有点基础的人应该都可以看懂,实在不懂也可以直接copy过去使用。后续会不定期更新一些视频业务线可能会用到的爬虫小案例,比如一些视频网站上视频信息爬取、评论爬取、用户信息爬取等等吧,同样可直接copy使用。如果有类似需求,可以在评论区回复需求,我会定期整理发出来。
这个案例中关注的电影豆瓣信息包括链接、片名、导演、演员、类型、地区、上映日期、别名、豆瓣评分、评分人数、介绍,如果还需要别的信息,可以自行完善代码,也可在评论区补充需求,我定期完善更新。

代码

该例中用的是BeautifulSoup方法。使用其他方法结构都是类似的,只是解析方法不同,可以自行修改。

# 已知豆瓣ID时,爬取影片基本信息
# 把已知的豆瓣ID存到项目文件中的'dubanIDs.xlsx'文件中即可,程序运行时自动导入该文件
import random
import numpy as np
from bs4 import BeautifulSoup #解析包
import requests #请求包
import pandas as pd
import json
import time # 可用于设置休眠时间,控制爬虫频率
from threading import Thread   

User_Agents =[
    'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
    'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
    'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1',
    'Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11',
    'Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
]

doubanIDs_dataframe = pd.read_excel('doubanIDs.xlsx') # 把目标影片的豆瓣id存到这个文件中
doubanID_array = np.array(doubanIDs_dataframe)
doubanID_list = doubanID_array.tolist()
print(doubanID_list)
doubanIDs=[]
for i in range(0,len(doubanID_list)):
    doubanID = doubanID_list[i]
    ID = doubanID[0]
    doubanIDs.append(ID)
print(doubanIDs)
# 根据豆瓣id列表构建出一个url列表
urls = []
for doubanID in doubanIDs:
    url = 'https://movie.douban.com/subject/'+ str(doubanID)
    urls.append(url)
print(urls)

allinfo=[]
# 定义一个函数,用来爬取一个电影的信息,并把信息写入指定excel
def getinfo(url):
    wdata = requests.get(url, headers={
    
    'User-Agent': random.choice(User_Agents)})
    wsoup = BeautifulSoup(wdata.text, 'lxml')
    names = wsoup.select('#content > h1 > span:nth-child(1)')
    info_all = wsoup.select('#info')
    data_one = info_all[0].get_text() if info_all else ""
    data_two = data_one.split('\n')
    directors = data_two[1].strip('导演: ') if len(data_two)>1 else ""
    actors = data_two[3].strip('主演: ') if len(data_two)>3 else ""
    types = data_two[4].strip('类型: ') if len(data_two)>4 else ""
    regions = data_two[5].strip('制片国家/地区: ') if len(data_two)>5 else ""
    reltimes = data_two[7].strip('上映日期: ') if len(data_two)>7 else ""
    secnames = data_two[9].strip('又名: ') if len(data_two)>9 else ""
    doubanscores = wsoup.select('#interest_sectl > div.rating_wrap.clearbox > div.rating_self.clearfix > strong')
    sconumbers = wsoup.select('#interest_sectl > div.rating_wrap.clearbox > div.rating_self.clearfix > div > div.rating_sum > a > span')
    introductions = wsoup.select('#link-report > span')
    info = {
    
    
        'url': url,#链接
        'name': names[0].get_text() if names else "",#片名
        'director':directors if directors else "",#导演
        'actor':actors if actors else "",#演员
        'type':types if types else "",#类型
        'region':regions if regions else "",#地区
        'reltime':reltimes if reltimes else "",#上映日期
        'secname':secnames if secnames else "",#别名
        'doubanscore': doubanscores[0].get_text() if doubanscores else "",#豆瓣评分
        'sconumber': sconumbers[0].get_text() if sconumbers else "",#评分人数
        'introduction': introductions[0].get_text().strip() if introductions else ""#介绍
    }
    allinfo.append(info)
    df = pd.DataFrame(allinfo)
    df.to_excel('douban_IDtest.xlsx', sheet_name='Sheet1')
# 上面一行中有爬取下来的影片信息存入的Excel的名称,可任意修改,文件路径是项目文件下
# 注:若项目文件中已有该名称的Excel文件,会自动覆盖,若不想被覆盖,需更改文件名或另存原文件

# 循环遍历url列表
for single_url in urls:
    print(single_url)
    getinfo(single_url)
    seconds = random.uniform(3,4) 
    time.sleep(seconds) # 设置休眠时间3-4秒

总结

针对于一些基本的爬虫场景,一般仅关注一种方法即可,换句话说,熟练掌握其中的一种方法,一般就可以解决大多数的爬虫场景,但不同的爬虫场景、不同的页面结构,使用不同的方法在性能、速度等方面上会有不同,也会出现某种方法不合适的情况。网络爬虫虽然只是个应用工具,多数情况下解决当下问题即可,但是其中也会遇到很多细节问题,如果有时间可以先进行系统学习,再开始场景应用。

链接

猜你喜欢

转载自blog.csdn.net/weixin_44740949/article/details/108592492