selenium爬取京东懒加载的商品信息
1.页面分析
- 1.页面分析
- 2.滑动滚动条获取完整页面源码
- 3.解析源码获取标签内容
- 4.保存信息至数据库
- 5.运行结果
首先给出要爬取数据的url: 京东
进入页面后,显示在界面上的图片已经加载完成,但是没有显示在屏幕上的内容,是没有加载的,只有当我们拖动界面,才会对相应资源进行请求和加载,我们如果用requests模块直接去请求获取页面源码数据,获取的源码肯定不完整。
这时就可以用selenium模拟浏览器的操作,通过拖动界面模拟人浏览,使浏览器资源加载完成后,再去获取页面源码,此时获取的内容就相对完整了。
本次爬取内容是300条商品信息,书籍名称、价格、图片下载链接,获取后将其保存到mysql数据库中。
先选取滑动滚动条的参照标签,执行JS代码,滑动滚动条到此标签位置,这里为了图片能够完全加载,将整个页面分为6部分,拖动六次后再获取页面源码。 代码如下:
def get_page_text(url): driver.get(url) sleep(random.random()*3) for i in range(10, 61, 10): sleep(1) target = driver.find_element_by_xpath(f'//*[@id="J_goodsList"]/ul/li[{i}]') driver.execute_script("arguments[0].scrollIntoView();", target) sleep(random.random()) page_text = driver.page_source return page_text3.解析源码获取标签内容
现在已经得到了加载完成后的页面数据,此时根据浏览器自带的工具,定位到图片列表具体的位置,大致如下。
将获取的li标签保存到列表中,再在li标签中定位书籍名称、价格、图片地址。
书籍名称:
书籍价格:
图片地址:
代码如下:
# 数据解析获取标签信息 def parse_page(page_text): tree = etree.HTML(page_text) li_list = tree.xpath('//*[@id="J_goodsList"]/ul/li') book_name_list = [] # 书籍名称 book_price_list = [] # 书籍价格 book_imageUrl_list = [] # 书籍图片 count = 0 for li in li_list: book_name_list.append(''.join(li.xpath('.//div[@class="p-name"]/a/em//text()'))) book_price_list .append(li.xpath('.//div[@class="p-price"]/strong/i/text()')[0]) # 由于网速的不稳定,可能有的图片没有加载完成,获取的数据可能为空 image_url = li.xpath('.//div[@class="p-img"]/a/img/@src') if len(image_url) == 0: # 若图片未加载出来,图片的url的值为img标签的data-lazy-img标签值 image_url = li.xpath('.//div[@class="p-img"]/a/img/@data-lazy-img') book_imageUrl_list.append('http:' + image_url[0]) return connectDB(book_name_list, book_price_list, book_imageUrl_list)4.保存信息至数据库
代码如下:
# 连接数据库并保存 def connectDB(book_name_list, book_price_list, book_imageUrl_list): conn = pymysql.Connect(host = '127.0.0.1', port = 3306, user = 'root', password='password', db='books_jd', charset='utf8') # 创建游标对象 cursor = conn.cursor() for i in range(len(book_name_list)): sql = 'INSERT INTO books(name, price, image_url) VALUES ("{0}","{1}","{2}")'.format(book_name_list[i], book_price_list[i], book_imageUrl_list[i]) try: cursor.execute(sql) conn.commit() # 事务提交 except Exception as e: print(e) conn.rollback() # 事务回滚 conn.close() cursor.close()
主函数代码:
if __name__ == '__main__': j = [1, 57, 117, 176, 236] for i in range(1,10,2): url = 'https://search.jd.com/Search?keyword=python&wq=python&page={0}&s={1}&click=0'.format(i,j[(i-1)//2]) page_text = get_page_text(url) parse_page(page_text) sleep(random.random()*4) print('第{}页已爬取成功!'.format((i+1)//2)) # 退出并清除浏览器缓存 driver.quit()5.运行结果