1.准备工作
1.1访问动态页面必须先安装selenium
在cmd界面下:
pip3 install selenium
测试是否安装成功
python3
import selenium
1.2再安装Chromedrive
首先必须查看chrome浏览器的版本号,在
中的"帮助"下的"关于Google Chrome",点开就可以看到:
,然后在"http://npm.taobao.org/mirrors/chromedriver/"中找到对应版本下载,
然后解压到"C:\Users\asus\AppData\Local\Programs\Python\Python37\Scripts"(需要改为自己的Python路径)路径下,即Python的安装路径下的Scripts中。
然后再配置环境变量。
接着需要测试是否安装成功,在cmd模式下输入
chromedriver
就可以看到如下图的截图,途中的ChromeDriver版本号和Google Chrome的版本号一致。
2.爬虫代码
2.1核心——动态访问页面代码
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://book.qidian.com/info/1027441448')
lis = browser.find_elements_by_css_selector('.fans-slide li')
for li in lis:
print(li.find_element_by_css_selector('a').get_attribute('href'))
print(browser.page_source)
browser.close()
2.2项目目标
获取起点月票排行榜(“https://www.qidian.com/rank/yuepiao?style=1”)的所有书籍,
并且获取每本书籍下的读者链接,
然后根据链接获得读者地址
如果读者没有设置地址就跳过,不将该读者写入文件。
2.3详细设计
2.3.1 将读者信息写入文件write_to_file(content)
def write_to_file(content):
with open('result_qidian.txt', 'a', encoding='utf-8') as f:
f.write(json.dumps(content, ensure_ascii=False))
2.3.2 换行write_to_file_next()
def write_to_file_next():
with open('result_qidian.txt', 'a', encoding='utf-8') as f:
f.write('\n')
2.3.4 解析排行榜信息
用pyquery解析排行榜信息,获取’book_href’、‘book_name’、‘book_author’
def parse_one_page(html):
doc = pq(html)
items = doc('.main-content-wrap .rank-body .rank-view-list .book-img-text li')
for item in items.items():
book_href = item.find('div').find('h4').find('a').attr('href')
book_name = item.find('div').find('h4').find('a').text()
book_author_warp = item.find('div').find('p').find('a').text()
book_author_warp_items = book_author_warp.split(' ')
book_author = book_author_warp_items[0]
book_abstract = item.find('div').find('p').text().split()[1]
print("写入book_href")
write_to_file("book_href:")
write_to_file("https"+book_href)
print("写入book_name")
write_to_file("book_name:")
write_to_file(book_name)
write_to_file("book_authot:")
print("写入book_author")
write_to_file(book_author)
# print("写入book_abstract")
# write_to_file(book_abstract)
get_readers_info(book_href)
write_to_file_next()
return None
2.3.4 请求静态页面信息
def get_one_page(url):
response = requests.get(url, headers=headers)
print(response.status_code)
if response.status_code == 200:
return response.text
return None
2.3.5 解析书籍页面信息
根据’parse_one_page(html)'获取的’book_href’信息,访问书籍页面,解析书籍页面,获取读者的链接
def get_readers_info(url):
time.sleep(1+random.random()*2)
browser = webdriver.Chrome()
browser.get("https:"+url)
lis = browser.find_elements_by_css_selector('.fans-slide li')
for li in lis:
reader_href = li.find_element_by_css_selector('a').get_attribute('href')
address = get_reader_address(reader_href)
if address is None:
continue
write_to_file({
'reader_href': reader_href,
'address': address
})
browser.quit()
2.3.6 解析读者页面信息
def get_reader_address(reader_href):
html_reader = get_one_page(reader_href)
doc = pq(html_reader)
infos = doc('.header-msg-desc')
print(infos.text())
info = infos.text().strip().split('/')
if len(info) < 2:
return None
else:
return info[1].strip()
2.4 遇到的问题
2.4.1 selenium 问题:OSError: [WinError 6] 句柄无效
解决方案:
关闭driver 时 , 使用 driver.quit()代替 driver.close()。
分析:
之前使用 driver.close() 时,用例执行结束有时会不能成功关闭chromedriver.exe,导致后台含有多个chromedriver.exe 进程(可以通过任务管理器查看)。
改用 driver.quit()之后,用例执行结束可以看到后台不会含有 chromedriver.exe 进程
区别:
close:只会关闭焦点所在的当前窗口
quit:会关闭所有关联的窗口
所以推荐使用quit 。
解决方案:
关闭driver 时 , 使用 driver.quit()代替 driver.close()。
分析:
之前使用 driver.close() 时,用例执行结束有时会不能成功关闭chromedriver.exe,导致后台含有多个chromedriver.exe 进程(可以通过任务管理器查看)。
改用 driver.quit()之后,用例执行结束可以看到后台不会含有 chromedriver.exe 进程
区别:
close:只会关闭焦点所在的当前窗口
quit:会关闭所有关联的窗口