今天要爬取豆瓣电影榜单的top250电影的一些信息,利用selenium自动化的跳转和点击,并结合requests方法,用BeautifulSoup大法,最终成功提取了top250的电影名,所有主演,年份,评分,电影简介,想看的人数,并将数据存进了MongoDB里面。
接下来,介绍一下步骤。
首先,通过自动化软件selenium,进入豆瓣首页,并模拟点击操作,进入top250页面
#这里需要导入的模块
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
#进入豆瓣首页
def get_to_douban(browser):
douban_page=browser.get('https://www.douban.com/')
#进入top250页面
def get_to_top250(browser):
get_to_douban(browser)
film_botton=browser.find_element_by_css_selector('#anony-nav > div.anony-nav-links > ul > li:nth-child(2) > a')
film_botton.click()
try:
rate_botton=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#db-nav-movie > div.nav-secondary > div > ul > li:nth-child(4) > a')))
rate_botton.click()
except TimeoutException as e:
print(e)
rate_botton=browser.find_element_by_link_text(u'排行榜')
rate_botton.click()
try:
top_botton=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#douban-top250 > div.douban-top250-hd > h2 > span > a')))
top_botton.click()
except TimeoutException as e:
print(e)
top_botton=browser.find_element_by_partial_link_text(u'全部')
top_botton.click()
return browser.page_source #返回页面资源
进入了top250页面,那么接下来就是要提取每部电影的链接
#下面我用了BeautifulSoup和re两种方法解析了这个页面,并且都成功得到了每部电影的链接
def parser_index_page(html):
# urls_list=[]
# Soup=BeautifulSoup(html,'lxml')
# ol=Soup.find('ol',class_="grid_view")
# li=ol.find_all('li')
# for i in li:
# url=i.find('a').get('href')
# urls_list.append(url)
#上面使用BeautifulSoup方法解析页面,接下来用正则表达式解析页面
pattern=re.compile(''
,re.S)
ol=pattern.search(html).group() # 只用加了group才能是一个text文本,否则只是一个对象
url_pattern=re.compile('https://movie.douban.com/subject/\d+?/',re.S)
urls1=url_pattern.findall(ol)
urls=set(urls1) # 用set去重
urls_list=list(urls) #强制转换回list
return urls_list
#下面使用的是re正则表达式进行的匹配
获得电影链接后,我就想着用requests模块,对链接进行请求,然后用BeautifulSoup解析出我想要在每部电影中要提取的信息
所以接下来,我建立了一个parser_one_movie函数,用于对每部电影进行提取,函数的参数是url,每部电影的链接,即上一部中提取的链接
def parser_one_movie(url):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36'}
html = requests.get(url, headers=headers, verify=False)
Soup = BeautifulSoup(html.text, 'lxml')
title = Soup.find('h1').find('span', property="v:itemreviewed").get_text()
year = Soup.find('h1').find('span', class_="year").get_text()
atrrs = Soup.find('span', class_='actor').find('span', class_="attrs").find_all('a', rel="v:starring")
names = []
for i in atrrs:
name = i.get_text()
names.append(name)
score = Soup.find('div', id="interest_sectl").find('div', class_="rating_self clearfix").get_text().strip()
short = Soup.find('span', property="v:summary").get_text().strip()
number = Soup.find('div', class_="rating_sum").find('a', class_="rating_people").get_text()
a = {'title': title, 'year': year, 'names': names, 'score': score, 'short': short, 'number': number}
db.insert_one(a) # 直接在这里将每条数据都插进了MongoDB中
这样的话,我就将一个页面的所有电影的信息提取并存储到了MongoDB中了
接下来在用selenium模拟点击,点击‘下页’,完成页面的转换,代码如下:
def auto_jump_page(browser):
next=wait.until(EC.presence_of_element_located((By.LINK_TEXT,u'后页>')))
next.click()
return browser.page_source
这样我们基本上就将整个过程中需要的函数建立完成了,接下来我们只需要进行一下整合操作,建立一个main函数:
def main(browser,wait):
get_to_douban(browser)
html=get_to_top250(browser)
urls_list=parser_index_page(html)
for i in urls_list:
try:#这里为了提高代码的健壮性,我建立一个try语句进行错误的捕捉,确实,有几部电影在解析页面时出现了None错误
parser_one_movie(i)
except Exception as e:
print(e)
for x in range(0,9):
try:#这边也是,防止页面解析的失误造成程序的停止,不过这里没有错误发生
htmls = auto_jump_page(browser)
urls_lists = parser_index_page(htmls)
for i in urls_lists:
try:
parser_one_movie(i)
except Exception as e:
print(e)
except Exception:
pass
以上基本上就是整个爬虫的代码,可以顺利完成爬取的过程
当然代码中有一个嵌套循环,可能比较慢,那可以在
` for x in range(0,9):
try:
htmls = auto_jump_page(browser)
urls_lists = parser_index_page(htmls)
for i in urls_lists:
try:
parser_one_movie(i)
except Exception as e:
print(e)
except Exception:
pass’
建立一个多线程加块爬取的速度