10丨Python爬虫:如何自动化下载王祖贤海报?
10丨Python爬虫:如何自动化下载王祖贤海报?
讲述:陈旸
时长08:39大小7.93M
爬虫的流程
如何使用 JSON 数据自动下载王祖贤的海报
如何使用 XPath 自动下载王祖贤的电影海报封面
总结
赞 21
提建议
精选留言(101)
- 滢2019-04-10说明两点问题: (一).留言里有人评论说用XPath下载的图片打不开,其原因是定义的下载函数保存路径后缀名为'.jpg',但是用XPath下载获得的图片url为'https://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p616.webp',本身图片为webp格式,所以若保存为jpg格式,肯定是打不开的。 (二). 老师在文章内讲的用XPath下载代码只能下载第一页的内容,并不是全部的数据,不知道大家有没有查看用xpath函数获得的数组,大家留言里的代码似乎和老师的一样,只能得到首页的内容,所以也是需要模拟翻页操作才能获得完整的数据。 以下是课后练习题:爬取宫崎骏的电影海报, Python3.6 IDLE >>> import json >>> import requests as req >>> from lxml import etree >>> from selenium import webdriver >>> import os >>> request_url = 'https://movie.douban.com/subject_search?search_text=宫崎骏&cat=1002' >>> src_xpath = "//div[@class='item-root']/a[@class='cover-link']/img[@class='cover']/@src" >>> title_xpath = "//div[@class='item-root']/div[@class='detail']/div[@class='title']/a[@class='title-text']" >>> driver = webdriver.Chrome('/Users/apple/Downloads/chromedriver') >>> driver.get(request_url) >>> html = etree.HTML(driver.page_source) >>> srcs = html.xpath(src_xpath) >>> print (srcs) #大家可要看下打印出来的数据是否只是一页的内容,以及图片url的后缀格式 >>> picpath = '/Users/apple/Downloads/宫崎骏电影海报' >>> if not os.path.isdir(picpath): os.mkdir(picpath) >>> def download(src, id): dic = picpath + '/' + str(id) + '.webp' try: pic = req.get(src, timeout = 30) fp = open(dic, 'wb') fp.write(pic.content) fp.close() except req.exceptions.ConnectionError: print ('图片无法下载') >>> for i in range(0, 150, 15): url = request_url + '&start=' + str(i) driver.get(url) html = etree.HTML(driver.page_source) srcs = html.xpath(src_xpath) titles = html.xpath(title_xpath) for src,title in zip(srcs, titles): download(src, title.text)展开
作者回复: 滢同学总结整理的很不错,大家都可以看下
共 2 条评论61 - rOMEo罗密欧2019-01-04老师请问一下:如果是需要用户登陆后才能爬取的数据该怎么用python来实现呢?
作者回复: 你可以使用python+selenium的方式完成账户的自动登录,因为selenium是个自动化测试的框架,使用selenium 的webdriver就可以模拟浏览器的行为。找到输入用户名密码的地方,输入相应的值,然后模拟点击即可完成登录(没有验证码的情况下) 另外你也可以使用cookie来登录网站,方法是你登录网站时,先保存网站的cookie,然后用下次访问的时候,加载之前保存的cookie,放到request headers中,这样就不需要再登录网站了
共 4 条评论45 - Bayes2019-07-30老师你这跳过了太多步骤了,表示对于python跟着你前几节课入门的人什么都不会,按着你的代码运行,要不就是没有定义,要不就是没有这个函数。刚开始的人也不知道哪个函数在哪个库,建议老师按照流程来一步一步给代码,要不就在最后给一个完整的代码示例,真的是学的很困难加上想放弃
作者回复: 慢慢来,有些代码放到GitHub上了,可以先跑下
共 8 条评论18 - caidy2019-01-05你需要使用浏览器的插件查看 XHR 数据,比如在 Chrome的开发者工具 在豆瓣搜索中,我们对“王祖贤”进行了模拟,发现 XHR 数据中有一个请求是这样的: https://www.douban.com/j/search_photo?q=王祖贤&limit=20&start=0 这个是如何查出来的,我使用chrome的开发者工具查看,但是查不到这部分,麻烦老师帮忙解答展开共 6 条评论16
- 伪君子2019-01-04那些用 ChromeDriver 的出现报错的可能是没有安装 ChromeDriver,或者是没给出 ChromeDriver 的路径,具体可以看看下面这篇文章。 https://mp.weixin.qq.com/s/UL0bcLr3KOb-qpI9oegaIQ
作者回复: 对的,主要是配置ChromeDriver的问题。有相同问题的人,可以看下这个留言
15 - LY2019-01-04#环境:Mac Python3 #pip install selenium #下载chromedriver,放到项目路径下(https://npm.taobao.org/mirrors/chromedriver/2.33/) # coding:utf-8 import requests import json import os from lxml import etree from selenium import webdriver query = '张柏芝' downloadPath = '/Users/yong/Desktop/Python/xpath/images/' ''' 下载图片 ''' def download(src, id): dir = downloadPath + str(id) + '.jpg' try: pic = requests.get(src, timeout=10) except requests.exceptions.ConnectionError: # print 'error, %d 当前图片无法下载', %id print('图片无法下载') if not os.path.exists(downloadPath): os.mkdir(downloadPath) if os.path.exists(dir): print('已存在:'+ id) return fp = open(dir, 'wb') fp.write(pic.content) fp.close() def searchImages(): ''' for 循环 请求全部的 url ''' for i in range(0, 22471, 20): url = 'https://www.douban.com/j/search_photo?q='+query+'&limit=20&start='+str(i) html = requests.get(url).text # 得到返回结果 print('html:'+html) response = json.loads(html,encoding='utf-8') # 将 JSON 格式转换成 Python 对象 for image in response['images']: print(image['src']) # 查看当前下载的图片网址 download(image['src'], image['id']) # 下载一张图片 def getMovieImages(): url = 'https://movie.douban.com/subject_search?search_text='+ query +'&cat=1002' driver = webdriver.Chrome('/Users/yong/Desktop/Python/xpath/libs/chromedriver') driver.get(url) html = etree.HTML(driver.page_source) # 使用xpath helper, ctrl+shit+x 选中元素,如果要匹配全部,则需要修改query 表达式 src_xpath = "//div[@class='item-root']/a[@class='cover-link']/img[@class='cover']/@src" title_xpath = "//div[@class='item-root']/div[@class='detail']/div[@class='title']/a[@class='title-text']" srcs = html.xpath(src_xpath) titles = html.xpath(title_xpath) for src, title in zip(srcs, titles): print('\t'.join([str(src),str(title.text)])) download(src, title.text) driver.close() getMovieImages()展开
作者回复: GoodJob
13 - juixv39372019-04-22怎么查看XHR数据啊,操作步骤跳过的话,学习的很困难10
- 飘2020-04-08感谢作者以及评论区的各位大神,终于完成了爬虫代码,总结一下小白编写时遇到的几个问题: 1)获取xpath时,chrome浏览器需要安装插件xpatn-helper; 2)使用python3.7,提前引入模块requests,lxml,selenium,安装这些模块需要更新pip至20版本; 3)模拟用户访问浏览器,需要下载chromedriver.exe,放入python.exe所在目录; 4)图片路径中出现导致编译失败的字符,使用replace替换报错字符。 具体代码如下: import os import requests from lxml import etree from selenium import webdriver search_text = "王祖贤" start = 0 limit = 15 total = 90 def download(img, title): dir = "D:\\数据分析\\python test\\query\\" + search_text + "\\" id = title.replace(u'\u200e', u'').replace(u'?', u'') .replace(u'/', u'or') if not os.path.exists(dir): os.makedirs(dir) try: pic = requests.get(img, timeout=10) img_path = dir + str(id) + '.jpg' fp = open(img_path, 'wb') fp.write(pic.content) fp.close() except requests.exceptions.ConnectionError: print('图片无法下载') def crawler_xpath(): src_img = "//div[@class='item-root']/a[@class='cover-link']/img[@class='cover']/@src" src_title = "//div[@class='item-root']/div[@class='detail']/div[@class='title']/a[@class='title-text']" for i in range(start,total,limit): request_url = "https://search.douban.com/movie/subject_search?search_text="+search_text+"&cat=1002&start="+str(i) driver = webdriver.Chrome() driver.get(request_url) html = etree.HTML(driver.page_source) imgs = html.xpath(src_img) titles = html.xpath(src_title) print(imgs,titles) for img, title in zip(imgs, titles): download(img, title.text) if __name__ == '__main__': crawler_xpath()展开
作者回复: Good Job!
共 3 条评论8 - 伪君子2019-01-04老师您好,我根据您的代码修改了一下,主要是添加了一个图片的目录,然后是下载大图。这里的大图是因为 /photo/thumb/public/ 这样的链接下载的图片是缩略图,只有把 thumb 替换成 l 之后下载的图片才是相对来说的大图。replace 方法和 re 中的 sub 方法都能实现替换,我的疑问是哪个实现起来更高速一点呢?提前感谢老师,我写的代码在下面~ # coding:utf-8 import requests import json import re import os query = '王祖贤' path = os.getcwd() # 当前路径,可以替换成别的路径 picpath = path + '/' + query # 设置的图片目录 print(picpath) # 输出设置的图片目录 if not os.path.isdir(picpath): # 如果图片目录未创建则创建一个 os.mkdir(picpath) def download(src, id): dir = picpath + '/' + str(id) + '.jpg' try: pic = requests.get(src, timeout=10) except requests.exceptions.ConnectionError: # print 'error, %d 当前图片无法下载', %id print('图片无法下载') fp = open(dir, 'wb') fp.write(pic.content) fp.close() ''' for 循环 请求全部的 url ''' for i in range(0, 22471, 20): # url = 'https://www.douban.com/j/search_photo?q=' + query + '&limit=20&start=' + str(i) html = requests.get(url).text # 得到返回结果 response = json.loads(html, encoding='utf-8') # 将 JSON 格式转换成 Python 对象 print('已下载 ' + str(i) + ' 张图片') for image in response['images']: image['src'] = image['src'].replace('thumb', 'l') # image['src'] = re.sub(r'thumb', r'l', image['src']) print(image['src']) # 查看当前下载的图片网址 download(image['src'], image['id']) # 下载一张图片展开8
- germany2019-01-04老师:为什么我在豆瓣网查询图片的网址与你不一样?https://www.douban.com/search?cat=1025&q=王祖贤&source=suggest 。是什么原因?
作者回复: 咱们访问豆瓣查询图片的网址应该是一样的。只是我给出的是json的链接。方法是:用Chrome浏览器的开发者工具,可以监测出来网页中是否有json数据的传输,所以我给出的链接是json数据传输的链接 https://www.douban.com/j/search_photo?q=%E7%8E%8B%E7%A5%96%E8%B4%A4&limit=20&start=0
共 2 条评论6 - 图吐兔2020-01-11用的是python3 requests.get(url)获取所有图片的路径此处需要稍作修改。 headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36'} requests.get(url,header) 请求要带上header,里面只需要加上user-Agent。推测豆瓣应该是对user-Agent做了检查,用来返回适配客户端的页面。展开共 2 条评论5
- 許敲敲2019-01-04要下载所有James 哈登的图片
作者回复: NBA明星也是不错的选择
5 - Miracle2020-01-30之前都是现成的数据,然后进行数据分析工作,现在突然需要自己爬数据的时候,有点艰难啊,这是第一次学习爬虫,先直接跑老师的代码, 遇到了这样的一个问题下面的一个问题, 花了很大的劲才搞定这个问题。然后借助今天的这个机会,也顺便进行了Python爬虫入门的学习,基于这节课的基础,把课上的两个例子进行了小实战,并且还用Python爬虫写了两个其他的实战,包括Python自动下载小说,Python下载表格数据,在Python下载小说里面,又学习了正则表达式皮毛, Python下载表格数据中,又学习了bs4的皮毛,整理了今天的成果写成了博客进行记录Python爬虫快速入门(https://blog.csdn.net/wuzhongqiang/article/details/104119800)。 上面有这节课的详细笔记和四个小实战项目,感兴趣的可以参考参考。 今天收获挺大。 运行代码总是出错:JSONDecodeError: Expecting value: line 1 column 1 (char 0),这个怎么解决? 首先进行输出调试,输出了一下html这个变量,也就是reques.get(url).text 这个变量,发现返回的竟然是空。 那肯定json.loads的时候出错啊,所以问题就在这,查了一下资料,虽然不知道什么原因,但是加了一个请求头好了。 headers = { 'Cookie':'OCSSID=4df0bjva6j7ejussu8al3eqo03', 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' ' (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36', } 然后,再requests.get(url, headers=headers).text 这个问题就搞定。展开共 2 条评论4
- Geek_2008d92019-12-14为什么我总是response=json.loads那一行显示json.decoder.JSONDecoderError:expecting value:line 1 column 1(char 0) 呢,怎么解决啊,各位大佬
作者回复: JSON解析错误,可以使用try ... except ... 捕获下错误看看
共 3 条评论4 - Geek_c456262019-12-06老师,运行代码总是出错:JSONDecodeError: Expecting value: line 1 column 1 (char 0),这个怎么解决?
作者回复: 可以使用 try ... except ... 捕获下错误看看
共 7 条评论3 - qinggeouye2019-11-06https://github.com/qinggeouye/GeekTime/blob/master/DataAnalysis/10_crawl_xpath.py import os import requests from lxml import etree from selenium import webdriver search_text = '王祖贤' start = 0 # 请求 url 的 start 从 0 开始,每一页间隔 15,有 6 页 total = 90 limit = 15 # 电影海报图片地址 src_xpath = "//div[@class='item-root']/a[@class='cover-link']/img[@class='cover']/@src" # 电影海报图片title title_xpath = "//div[@class='item-root']/div[@class='detail']/div[@class='title']/a[@class='title-text']" # 保存目录 pic_path = '10/xpath' # 相对目录 # WebDriver 创建一个 Chrome 浏览器的 drive driver = webdriver.Chrome('./chromedriver') # MAC 版本 # 创建图片保存路径 def mk_save_path(pic_path_): if not os.path.exists(pic_path_): os.makedirs(pic_path_) return os.getcwd() + '/' + pic_path_ + '/' # 下载图片 def download(src, pic_id, save_path_): directory = save_path_ + str(pic_id) + '.jpg' try: pic = requests.get(src, timeout=10) fp = open(directory, 'wb') fp.write(pic.content) fp.close() except requests.exceptions.ConnectionError: print('图片如无法下载') def get_response_xpath(): save_path = mk_save_path(pic_path) for i in range(start, total, limit): requests_url = 'https://search.douban.com/movie/subject_search?search_text=' + search_text + '&cat=1002' + \ '&start=' + str(i) driver.get(url=requests_url) html = etree.HTML(driver.page_source) src_list = html.xpath(src_xpath) title_list = html.xpath(title_xpath) for src, title in zip(src_list, title_list): download(src, title.text, save_path) if __name__ == '__main__': get_response_xpath()展开
作者回复: Good Job
3 - Yezhiwei2019-01-04用Scrapy爬取数据更方便哈,请问老师怎么做一个通用的爬虫呢?比如要爬取文章标题和内容,不同的网站Xpath结构不一样,如果源少的话可以分别配置,但如果要爬取几百上千的网站数据,分别配置Xpath挺麻烦的。请问这个问题有什么解决方案吗?谢谢
作者回复: 网站的抓取和网页的HTML结构有很大关系,所以一般都是用XPath解析,如果你用第三方工具,比如八爪鱼,也是要个性化的把每个网站流程模拟出来,这样工具会自动定位XPath 网站的抓取和网页的HTML结构有很大关系,所以一般都是用XPath解析,如果你用第三方工具,比如八爪鱼,也是要个性化的把每个网站流程模拟出来,这样工具会自动定位XPath 如果想要做一个通用的解决方案,自动识别文章的标题和内容。就需要先把HTML下载下来,然后将HTML解析为DOM树,再对每个节点做评估(文章标题还是内容的可能性) 这样做的好处是通用性强,缺点就是可能会出错。
3 - Geek_c456262019-12-06运行代码总是出现错误:JSONDecodeError: Expecting value: line 1 column 1 (char 0)2
- 爱喝酸奶的程序员2019-02-26有个问题selenium,是用来自动化测试的,他回打开浏览器……我做爬虫是不想让代码打开浏览器,只想要他爬取的动作~要怎么办呢?
作者回复: 可以用 无界面的puppetteer
2 - ldw2019-01-06可以用爬虫爬谷歌吗?会不会被当成恶意攻击?不会引来国际官司吧。2