他的代码比较简单,主要有如下的步骤:使用BeautifulSoup
库,打开百度贴吧的首页地址,再解析获得id
为new_list
标签底下的img
标签,最后将img
标签的图片保存下来。javascript
headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36' } data=requests.get("https://tieba.baidu.com/index.html",headers=headers) html=BeautifulSoup(data.text,'lxml')
前面提到过,有部分图片是动态加载的,那么首先咱们得弄清楚,这部分图片是怎么动态加载的。在浏览器中打开百度贴吧的首页,能够明显的看到,在往下滚动滚动条的时候,当滚动到底部的时候,滚动条缩短了,并向上移动了一段距离。这个现象也正是有DOM
元素动态的添加到了html
文档的一个表现。动态加载数据无非就是ajax
请求,而ajax
本质上就是XMLHttpRequest
请求(简称xhr
)。在谷歌浏览器中,咱们能够经过开发者工具的network
面板来监测xhr请求。css
刚打开首页时的xhr
请求,这里的请求都和要爬取的图片无关。html
滚动条向下第1次滚动到底部,这里请求的是第20-40
条热门动态,包含要爬取图片。java
滚动条向下第2次滚动到底部,这里请求的是第40-60
条热门动态,包含要爬取图片。而且返回的的has_more:false
代表没有跟多数据了。python
滚动条向下第3次滚动到底部,再无xhr
请求。git
根据上面的分析,咱们已经明白,单纯使用BeautifulSoup
进行爬虫的时候,只能爬取到1-20
条热门动态里面的图片。为了爬取到完整的热门动态里面的图片,咱们则须要模拟浏览器的滚动条滚动,让网页去触发xhr
请求更多的热门动态。github
在python中,若是须要模拟浏览器的行为,可使用selenium
库。selenium
库是一个自动化测试框架,能够用来模拟测试浏览器的各类行为,这里咱们使用它来模拟浏览器打开百度贴吧的首页,并模拟滚动条向下滚动到底部的操做。web
pip install selenium
火狐浏览器驱动,其下载地址是:https://github.com/mozilla/geckodriver/releasesajax
谷歌浏览器驱动,其下载地址是:http://chromedriver.storage.googleapis.com/index.html?path=2.33/chrome
opera浏览器驱动,其下载地址是:https://github.com/operasoftware/operachromiumdriver/releases
对照本身电脑安装的浏览器和对应的版本,分别从上面的地址下载驱动文件,也能够从个人github项目中统一下载以上几个驱动(地址:https://github.com/Sesshoumaru/attachments/tree/master/Selenium%20WebDriver)。下载解压后,将所在的目录添加系统的环境变量中。固然你也能够将下载下来的驱动放到python安装目录的lib
目录中,由于它自己已经存在于环境变量(我就是这么干的)。
要使用selenium
先须要定义一个具体browser
对象,这里就定义的时候就看你电脑安装的具体浏览器和安装的哪一个浏览器的驱动。这里以火狐浏览器为例:
from selenium import webdriver browser = webdriver.Firefox()
再模拟打开贴吧首页:
browser.get("https://tieba.baidu.com/index.html")
再模拟滚动条滚动到底部
for i in range(1, 5): browser.execute_script('window.scrollTo(0, document.body.scrollHeight)') time.sleep(1)
最后再使用BeautifulSoup
,解析图片标签:
html = BeautifulSoup(browser.page_source, "lxml") imgs = html.select("#new_list li img")
必须安装浏览器和浏览器驱动,而且浏览器和浏览器驱动要配到
即若是使用谷歌浏览器模拟网页行为,则须要下载谷歌浏览器驱动; 若是使用火狐浏览器模拟网页行为,则须要下载火狐浏览器驱动
浏览器驱动所在的目录要在环境变量中,或者定义浏览器browser
的时候指定驱动的路径
from selenium import webdriver browser = webdriver.Firefox() browser.get("https://tieba.baidu.com/index.html") new_list = browser.find_element_by_id('new_list') user_name = browser.find_element_by_name ('user_name') active = browser.find_element_by_class_name ('active') p = browser.find_element_by_tag_name ('p') # find_element_by_name 经过name查找单个元素 # find_element_by_xpath 经过xpath查找单个元素 # find_element_by_link_text 经过连接查找单个元素 # find_element_by_partial_link_text 经过部分连接查找单个元素 # find_element_by_tag_name 经过标签名称查找单个元素 # find_element_by_class_name 经过类名查找单个元素 # find_element_by_css_selector 经过css选择武器查找单个元素 # find_elements_by_name 经过name查找多个元素 # find_elements_by_xpath 经过xpath查找多个元素 # find_elements_by_link_text 经过连接查找多个元素 # find_elements_by_partial_link_text 经过部分连接查找多个元素 # find_elements_by_tag_name 经过标签名称查找多个元素 # find_elements_by_class_name 经过类名查找多个元素 # find_elements_by_css_selector 经过css选择武器查找多个元素
btn_more = browser.find_element_by_id('btn_more') print(btn_more.get_attribute('class')) # 获取属性 print(btn_more.get_attribute('href')) # 获取属性 print(btn_more.text) # 获取文本值
btn_more = browser.find_element_by_id('btn_more') btn_more.click() # 模拟点击,能够模拟点击加载更多 input_search = browser.find_element(By.ID,'q') input_search.clear() # 清空输入
# 执行JavaScript脚本 browser.execute_script('window.scrollTo(0, document.body.scrollHeight)') browser.execute_script('alert("To Bottom")')