作者:IPIDEA
2022-10-08 14:15:20
#coding:utf8
"""整站爬虫"""
fromgeventimportmonkey
monkey.patch_all()
fromurlparseimporturljoin
importrequests
fromlxmlimportetree
fromgevent.poolimportPool
fromgevent.queueimportQueue
base_url=https://book.douban.com
#种子URL
start_url=https://book.douban.com/tag/?view=type&icn=index-sorttags-all
#解析规则
rules={
#标签页列表
list_urls:"//table[@class=tagCol]/tbody/tr/td/a/@href",
#详细页列表
detail_urls:"//li[@class=subject-item]/div[@class=info]/h2/a/@href",
#页码
page_urls:"//div[@id=subject_list]/div[@class=paginator]/a/@href",
#书名
title:"//div[@id=wrapper]/h1/span/text()",
}
#定义队列
list_queue=Queue()
detail_queue=Queue()
#定义协程池
pool=Pool(size=10)
defcrawl(url):
"""首页"""
response=requests.get(url)
list_urls=etree.HTML(response.text).xpath(rules[list_urls])
forlist_urlinlist_urls:
list_queue.put(urljoin(base_url,list_url))
deflist_loop():
"""采集列表页"""
whileTrue:
list_url=list_queue.get()
pool.spawn(crawl_list_page,list_url)
defdetail_loop():
"""采集详情页"""
whileTrue:
detail_url=detail_queue.get()
pool.spawn(crawl_detail_page,detail_url)
defcrawl_list_page(list_url):
"""采集列表页"""
html=requests.get(list_url).text
detail_urls=etree.HTML(html).xpath(rules[detail_urls])
#详情页
fordetail_urlindetail_urls:
detail_queue.put(urljoin(base_url,detail_url))
#下一页
list_urls=etree.HTML(html).xpath(rules[page_urls])
forlist_urlinlist_urls:
list_queue.put(urljoin(base_url,list_url))
defcrawl_detail_page(list_url):
"""采集详情页"""
html=requests.get(list_url).text
title=etree.HTML(html).xpath(rules[title])[0]
printtitle
defmain():
#1.标签页
crawl(start_url)
#2.列表页
pool.spawn(list_loop)
#3.详情页
pool.spawn(detail_loop)
#开始采集
pool.join()
if__name__==__main__:
main()
要抓取豆瓣网站的全站数据,执行流程如下:
找到入口,即进入图书标签页,提取所有标签URL。
输入每个标签页,提取所有列表URL。
输入每个列表页面,提取每个页面的详细信息URL还有下一页URL。
输入每个详细页面,获取书籍信息。
这种循环,直到数据被捕获。
这是抓住整个网站的想法,简单,分析我们阅读网站的行为轨迹,用程序自动化要求,抓住。