1、用selenium自动爬取淘宝美食的商品信息,先定义search方法,该方法用来在搜索框中输入“美食”,然后点击搜索按钮。浏览器加载需要时间,要判断浏览器加载成功再执行下一步的操作,其使用方法可在python-selenium官网查看waits相关的介绍,部分代码复制粘贴即可。设置的条件要在指定的时间内加载出来,否则会抛出异常,使用try回归这个方法。
Input为搜索框,submit为搜索按钮,判断完成后搜索框中输入“美食”,然后点击搜索按钮,最后main方法调用。
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
browser=webdriver.Chrome()
def search():
try:
browser.get("https://www.taobao.com")
input = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, "#q")))
submit = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#J_TSearchForm > div.search-button > button")))
input.send_keys("美食")
submit.click()
except TimeoutException :
search()
def main():
search()
if __name__ == '__main__':
main()
因为search方法外还会有等待判断,可以把WebDriverWait(browser, 10)放在代码头
2、在翻页解析代码之前,要先获取总页数,输入“美食”点击搜索后,需要等待页数加载出来才能进行下一步操作,所以,还需要再加一个等待判断,判断放在search方法里。
total = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#mainsrp-pager > div > div > div > div.total"))) return total.text
在main函数中调用,因为返回的total含有汉子,即汉子与数字共同存在,用re正则表达式解析,提取数字,并把字符串转化为整形。
total = search() total = int(re.compile('(\d+)').search(total).group(1)) print(total)
3、进行翻页,翻页有两种方法,一种是直接点击下一页,另一种是在页数框中输入
页码,点击确定。
还需要判断翻页是否成功,通过高亮显示的数字与页数框中的数字比较判断,可以在搜索框中输入页码进行翻页,然后判断是否与高亮显示的页码相同。
定义翻页方法:input为页数框,submit为确定按钮,先清除页数框,在传入参数,点击按钮,然后判断两个是否相同。
next_page(page_number): try: input = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#mainsrp-pager > div > div > div > div.form > input"))) submit = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#mainsrp-pager > div > div > div > div.form > span.btn.J_Submit"))) input.clear() input.send_keys(page_number) submit.click() wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > ul > li.item.active > span'),str(page_number))) except TimeoutException: next_page(page_number)
在main函数中调用,需要遍历总页数
for i in range(1, total + 1): next_page(i)
4、解析网页
分析网页源代码可知每个商品的信息在id为mainsrp-itemlist下的items .item中,
所以先判断所需商品的信息是否加载出来,所需商品信息都加载出来后,用page_source得到网页源代码,用pyquery解析,再调用items()方法获得所有选择的内容,然后再分别获取product信息,用find获取内部元素
def get_products(): wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-itemlist .items .item'))) html = browser.page_source doc = pq(html) items = doc('#mainsrp-itemlist .items .item').items() for item in items: product = { 'price': item.find('.price').text(), # 价格 'image': item.find('.pic .img').attr('src'), # 图片 'deal': item.find('.deal-cnt').text()[:-3], # 成交数,去掉末尾的“人付款” 'title': item.find('.title').text(), #标题 'location': item.find('.location').text(), #地点 'shop': item.find('.shop').text() #店名 } print(product)
5、调用
每次翻页都要获取页面的商品信息,所以要在next_page()方法中调用
get_products()
运行结果:
6、存储到mongodb数据库
MONGO_URL = 'localhost' MONGO_DB = 'taobao' MONGO_TABLE = 'meishi' client = pymongo.MongoClient(MONGO_URL) db = client[MONGO_DB]
def save_to_mongo(result): try: if db[MONGO_TABLE].insert(result): print("存储到mongodb成功",result) except Exception: print("存储到mongodb失败")