前言:那么什么是爬虫呢?我们把互联网上有价值的信息都比作大蜘蛛网,每个节点都是存储的数据,蜘蛛网上的蜘蛛比作爬虫,爬虫是可以自动收集网络信息的程序。从网上收集所有有价值的信息,将网站的html和js返回的照片爬到当地,使用起来很方便。(约翰f肯尼迪)。
- 实践:爬取电影天堂电影详情页
- 网页分析及爬取第一页的详情页url
从电影天堂最新电影界面。可以看到其第一页url为 ,第二页为,第三第四页也类似。
from lxml import etree
import requests
url = ''
headers = {
'User_Agent':'Mozilla (Macintosh; Intel Mac OS X 10_13_6) AppleWebKi (KHTML, like Gecko) Chrome Safari;,
}
response = reque(url,headers=headers)
# re 是系统自己默认判断。但很遗憾判断错误,导致乱码出现。我们可以采取另外方式 re。自己指定格式解码
# print(re)
# print(re.decode('gbk'))
print(re.decode(encoding="gbk", errors="ignore"))
先以第一页为例,打印数据如下:
分析电影天堂 html 源代码,可以得出每个 table 标签就是一个电影
通过 xpath 拿到每个电影的详情url
html = e(text)
detail_urls = ("//table[@class='tbspan']//a/@href")
for detail_url in detail_urls:
print(detail_url) #加上域名即为详情 url
结果:
2.整理代码并爬取前7页的电影列表url.
from lxml import etree
import requests
# 域名
BASE_DOMAIN = ';
# url = ''
HEADERS = {
'User_Agent':'Mozilla (Macintosh; Intel Mac OS X 10_13_6) AppleWebKi (KHTML, like Gecko) Chrome Safari;,
}
def spider():
base_url = '{}.html'
for x in range(1,8):
url = ba(x)
print(url) # 求出每一页电影列表的url eg:
if __name__ == '__main__':
spider()
3.爬取每一部电影的详情页地址
def get_detail_urls(url):
response = reque(url, headers=HEADERS)
# re 是系统自己默认判断。但很遗憾判断错误,导致乱码出现。我们可以采取另外方式 re。自己指定格式解码
# print(re)
# print(re.decode('gbk'))
# print(re.decode(encoding="gbk", errors="ignore"))
text = re.decode(encoding="gbk", errors="ignore")
# 通过 xpath 拿到每个电影的详情url
html = e(text)
detail_urls = ("//table[@class='tbspan']//a/@href")
detail_urls = map(lambda url:BASE_DOMAIN+url,detail_urls) #这句意思相当于下面一段代码:替换列表中的每一个url
# def abc(url):
# return BASE_DOMAIN+url
# index = 1
# for detail_url in detail_urls:
# detail_url = abc(detail_url)
# detail_urls[index] = detail_url
# index+1
return detail_urls
4.抓取电影详情页的数据
# 解析详情页面
def parse_detail_page(url):
movie = {}
response = reque(url,headers = HEADERS)
text = re.decode('gbk', errors='ignore')
html = e(text)
# title = ("//div[@class='title_all']//font[@color='#07519a']") # 本行47行,下面已修改
# 打印出 [<Element font at 0x10cb422c8>, <Element font at 0x10cb42308>]
# print(title)
# 为了显示,我们需要转一下编码
# for x in title:
# prin(x,encoding='utf-8').decode('utf-8'))
# 我们是为了取得文字,所以修改47行
title = ("//div[@class='title_all']//font[@color='#07519a']/text()")[0]
movie['title'] = title
zoomE = ("//div[@id='Zoom']") [0] # 求出共同的顶级容器,方便后面求职
imgs = zoomE.xpath(".//img/@src") # 求出海报和截图
cover = imgs[0]
if len(imgs) > 1:
screenshot = imgs[1]
movie['screenshot'] = screenshot
# print(cover)
movie['cover'] = cover
infos = zoomE.xpath(".//text()")
for index,info in enumerate(infos):
if in('◎年 代'):
info = in("◎年 代", "").strip() # strip 去掉空格
movie['year'] = info
elif in("◎产 地"):
info = in("◎产 地", "").strip()
movie["country"] = info
elif in("◎类 别"):
info = in("◎类 别", "").strip()
movie["category"] = info
elif in("◎豆瓣评分"):
info = in("◎豆瓣评分", "").strip()
movie["douban_rating"] = info
elif in("◎片 长"):
info = in("◎片 长","").strip()
movie["duration"] = info
elif in("◎导 演"):
info = in("◎导 演", "").strip()
movie["director"] = info
elif in("◎主 演"):
actors = []
actor = in("◎主 演", "").strip()
ac(actor)
# 因为主演有很多个,再加上其在电影天堂中元素的特殊性,需要遍历一遍,在分别求出每一个演员
for x in range(index+1,len(infos)): # 从演员 infos 开始遍历,求出每一个演员
actor = infos[x].strip()
if ac("◎"): # 也就是到了标签 的 ◎ 就退出
break
ac(actor)
movie['actor'] = actors
elif in('◎简 介 '):
# info = in('◎简 介 ',"").strip()
for x in range(index+1,len(infos)):
if infos[x].startswith("◎获奖情况"):
break
profile = infos[x].strip()
movie['profile'] = profile
# print(movie)
elif in('◎获奖情况 '):
awards = []
# info = in("◎获奖情况 ", "").strip()
for x in range(index+1,len(infos)):
if infos[x].startswith("【下载地址】"):
break
award = infos[x].strip()
awards.append(award)
movie['awards'] = awards
# print(awards)
download_url = ("//td[@bgcolor='#fdfddf']/a/@href")[0]
movie['download_url'] = download_url
return movie
最后结果: