做者:xiaoyu
微信公众号:Python数据科学
知乎:Python数据分析师html
海贼王已经10年了,一路陪伴了咱们的点点滴滴。它热血,激情,感人,欢乐,吸引了无数男女老幼的牢牢跟随。
提及来还真有点当心酸,原谅博主也是个海贼迷,心中怀揣着很大的梦想,誓死也要成为海贼王的男人。
但现在梦想已经破灭了,由于博主有了女友...git
什么?说我是假粉丝,我上去就给你一巴掌!看到最后你就知道什么叫真粉儿!!github
说说咱们的正题,前面两篇爬虫学习介绍了正则
和BeautifulSoup
的内容,这里实际上是想借着这个机会给你们分享一下正则
和BeautifulSoup
解析的实战例子。服务器
目标实现比较简单,就是下载xxx网站上海贼王动漫的套图。爬取效果以下:微信
(截取了部分下载过程)多线程
(部分下载图片)app
采起了多线程爬取,总共1000
多张,都存在本地了。运维
本篇目的是使用正则+BeautifulSoup
,所以后面不更多赘述了。dom
经过开发者工具看到,全部的系列都是同一级别的节点,那么咱们首先应该作的是遍历全部页码,而后提取每页各个系列的连接。工具
接下来看看连接在哪。
小提示:红框内第一个是鼠标自动跟随,第二个是手机/PC切换,使用起来很是方便。
具体点开其中一个系列标签一看,咱们要的连接正是<a>标签
下的href属性
,可是你会发现有两个如出一辙的href属性,连接也同样,而咱们只须要一个,这就须要小处理一下了,提供两个思路:
这里博主用的第一种方法。
一样的过程,图片的连接在<p>标签
下的子节点<img>的src属性
里,依然使用BeautifulSoup就可轻松解决。
可是这里的网页排版有个问题,就是有的系列中多组图在一页中,而有的系列每页只有一张图,须要翻页查看。
解决方法是无论有没有翻页,都直接遍历该系列下的全部页,经过返回的状态码来判断下一步动做。
好了,解析的任务的分析差很少完成了,下面看看具体代码如何实现的。
下载系列连接:
def html_parse(self, num): try: url_make = self.url.format(num) html = requests.get(url_make, timeout=10) soup = BeautifulSoup(html.content, 'lxml') ul_tag = soup.find_all('ul', class_='spic pic1') soup1 = BeautifulSoup(str(ul_tag[0]), 'lxml') for counter, li_tag in enumerate(soup1.find_all('li')): soup2 = BeautifulSoup(str(li_tag), 'lxml') a_tag = soup2.find_all('a') href_list = re.findall(re.compile('href="(.+?)"'), str(a_tag)) if len(href_list) != 0: print('第 ' + str(num) + ' 页: ----第 ' + str(counter + 1) + '个连接:' + href_list[0] + ' ----') self.q.put(href_list[0]) sleep(random.randint(2, 3)) except requests.ConnectionError: pass
下载图片连接:
def picture_parse(self): try: sub_url = self.q.get() sub_url_base = sub_url[:-6] for page in range(1, 10): sub_url_new = sub_url_base + '_' + str(page) + '.shtml' html2 = requests.get(sub_url_new) if html2.status_code == 200: soup = BeautifulSoup(html2.content, 'lxml') div_tag = soup.find_all('div', id='pictureContent') soup1 = BeautifulSoup(str(div_tag[0]), 'lxml') for img_tag in soup1.find_all('img', src=re.compile('.+?')): soup3 = BeautifulSoup(str(img_tag), 'lxml') if soup3.img['src'] is not None: self.picture_link.append(soup3.img['src']) print(str('----' + soup3.img['alt']) + '连接 : ' + str(soup3.img['src']) + ' ----') sleep(random.randint(2, 3)) else: pass except requests.ConnectionError: pass
下载并储存图片到本地:
def picture_store(self): try: for num, link in enumerate(set(self.picture_link)): html3 = requests.get(link) picture_path = 'D:\Pictures_Downloaded\\' + 'pic' + str(num+1) + '.jpg' with open(picture_path, 'wb') as f: f.write(html3.content) except requests.ConnectionError: pass
多线程队列任务:
def main(self): page_num = 2 threads_0 = [] for i in range(1, page_num): t = Thread(target=self.html_parse, args=(i,), name='Thread-0') threads_0.append(t) for i in range(len(threads_0)): threads_0[i].start() for i in range(len(threads_0)): threads_0[i].join() threads_1 = [] for i in range(self.q.qsize()): t1 = Thread(target=self.picture_parse, args=(), name='Thread-1') threads_1.append(t1) for i in range(len(threads_1)): threads_1[i].start() for i in range(len(threads_1)): threads_1[i].join() self.picture_store()
注:爬取间隔能够适当再长点,减轻目标服务器的负担,也理解一下辛苦的运维工做人员。
代码比较简单,目的是在实战中掌握正则和BeautifulSoup解析方法
,欢迎你们指点和讨论。
完整代码已上传到Github,请参考:https://github.com/xiaoyusmd/...
这部分是为了兑现铁粉儿的承诺,不感兴趣可忽略。
博主库爱画画,素描,水彩,国画都学过点,固然这个是在wacom绘画板上,利用corel painter + photoshop
完成的。因为热爱海贼王动漫
,闲暇时间画了个各类海贼绘画。
如下是几张索隆桑的绘图(无水印),感兴趣的朋友能够收藏:)
关注微信公众号Python数据科学,获取 120G
人工智能 学习资料。