前言 上一篇有说BS4
这个库,这个库通过find,findall,select
等函数定位关键节点,获取想要的信息。
find,findall
函数用得少,平时用的都是select
函数
这个函数通过使用CSS 选择器
来定位数据,通过那篇文章,我觉得大多数人应该也是看得比较懵。
那就看操作吧。
实战 初级 先从天气预报 开始,就获取8-15天
的信息把,这里使用的是chrome浏览器
,通过快捷键f12
打开开发者工具。
先学会分析页面。确认目标,爬取8-15天的信息
在开发者工具中,点击一下这个鼠标
接下来鼠标放置在要爬取的位置点一下左键,此时就会定位到相应的源代码处。
8-15天的内容,根据源码可以看到,是由一个ul
标签包含起来的,下面子标签中span
big
啥的都有对应的class
类名和文本解释。
那么此时,要定位的地方找到了,那现在就是要设计合理的css 选择器
代码,来让程序定位到此处。
点击一下开发者工具,通过快捷键Ctrl +F
就会在底下弹出一个搜索框
先来了解下CSS 选择器
是如何定位class
或id
的。
根据上图指出,当要定位class
时,只需要给出类名,例如现在要爬的位置处,有一个ul
包含着的的class
类名为t clearfix
此时可以尝试着在搜索框中输入.t.clearfix
,由于类名中t
和clearfix
中间有一个空格,所以在搜索时,可以用. 号替代空格
此时,黄色的区域就是搜索到的位置,搜索框右边显示出,只找到一个结果。
定位到最外围的ul
后,在继续向里深入,可以看到所有信息都是在li
标签内的。
但是观察得知,由于有的li
标签存在类名t
,而有的是没有的。
这时候要搜索子标签,只需要一个空格,在继续输入就可以了。
如果输入.t.clearfix li.t
的话,就会发现没有类名的li
就无法匹配到
所以这时候要把.t
去掉,只需要匹配li
,就匹配到没有类名的li
了
.t.clearfix li
CSS选择器
的定位语法已经找到了,接下来就是编写代码
1.首先导入库 1 2 3 4 5 6 7 8 9 """ @author: @file: tianqi.py @time: 2020-11-11 20:28 @desc: """ import requestsfrom bs4 import BeautifulSoup
2.通过request获取页面信息 1 2 html =requests.get('http://www.weather.com.cn/weather15d/101280101.shtml' ) html.encoding='utf8'
3.调用bs4库 1 2 soup = BeautifulSoup(html.text,'lxml' ) clearfix = soup.select('.t.clearfix li' )
此时通过printf
打印一下看下结果。
可以看到,输出结果在一个[]
内,在Python中,要脱离这个[]
,只需要通过for
循环就可以了。
4.for循环 1 2 for clearfixs in clearfix: print(clearfixs)
此时每一段都是分工明确,输出出来,但是此时只需要里面的中文,哪些html
代码是不需要的,所以要提取文本。
这个时候可以使用get_text()
函数提取文本
1 2 for clearfixs in clearfix: print(clearfixs.get_text())
还有一些多余的换行,也可以去掉,使用replace
函数,这个函数不了解的可以百度,有参数解释,这里不做过多的解释
1 2 for clearfixs in clearfix: print(clearfixs.get_text().replace("\n" ,'' ))
完整代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 """ @author: @file: tianqi.py @time: 2020-11-11 20:28 @desc: """ import requestsfrom bs4 import BeautifulSouphtml =requests.get('http://www.weather.com.cn/weather15d/101280101.shtml' ) html.encoding='utf8' soup = BeautifulSoup(html.text,'lxml' ) clearfix = soup.select('.t.clearfix li' ) for clearfixs in clearfix: print(clearfixs.get_text().replace("\n" ,'' ))
高级
对一个经常获取背景图片的网站进行爬取,分析方式和上面大概相似,没多大区别,代码进行了封装,但是感觉太多层for,比较慢,想着优化一下,由于实在是太菜了,也不知道可以怎么优化了,将就着用吧。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 """ @author: Wrpzkb @file: wallhaven.py @time: 2020/12/10 9:44 @desc: """ import osimport requestsfrom bs4 import BeautifulSoupfrom requests import RequestExceptionheader = { "User-Agent" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36" , } def get_main (url ): try : response = requests.get(url,headers=header) if response.status_code == 200 : return response.text return None except RequestException: return None def get_link (response ): urls = [] soup = BeautifulSoup(response,'lxml' ) photourl = soup.select('.thumb-listing-page ul li .preview' ) for photourls in photourl: urls.append(photourls['href' ]) return urls def down_image (filename,url ): try : result = requests.get(url) with open ('images\{}' .format (filename), 'wb' )as f: for r in result.iter_content(): f.write(r) except Exception as e: print("error: " , e) def get_photo (photourl ): photo_num =1 for i in photourl: Photocontext = get_main(i) soup = BeautifulSoup(Photocontext,'lxml' ) phtocontenurl = soup.select('#showcase .scrollbox #wallpaper' ) for phtocontenurls in phtocontenurl: print('正在下载第{}张图片' .format (photo_num)) downloadurl = phtocontenurls['src' ] filename = downloadurl[31 :] if os.path.isfile('images\{}' .format (filename)): print('文件%s已经存在,正在下载下一张 ' %filename) continue down_image(filename, str (downloadurl)) photo_num += 1 def main (i ): url = 'https://wallhaven.cc/toplist?page={}' .format (i) html = get_main(url) photourl = get_link(html) if not os.path.exists('images' ): os.makedirs('images' ) get_photo(photourl) if __name__ == "__main__" : for i in range (1 , 132 ): main(i)