使用xpath编写多线程爬虫(线程数量至少4个,不使用scrapy)爬取杂文标签下 所有书籍(至少爬取前10页)的信息(包括书名、作者、出版社、出版 日期、页数、价格、ISBN号、豆瓣评分、评价人数、书籍封面、 URL),并按照豆瓣评分降序保存(以标签名称命名)
时间: 2023-07-03 20:28:57 浏览: 105
好的,这是一个比较复杂的任务,需要使用多线程和xpath进行爬取数据,并按照豆瓣评分进行排序。下面是一份可供参考的Python代码,希望对你有所帮助:
```python
import requests
from lxml import etree
import threading
from queue import Queue
import time
# 定义爬虫类
class Spider:
def __init__(self, tag):
self.tag = tag
self.base_url = 'https://book.douban.com/tag/' + tag
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
self.q = Queue() # URL队列
self.book_list = [] # 书籍列表
# 获取页面内容并解析
def get_html(self, url):
try:
r = requests.get(url, headers=self.headers, timeout=30)
r.raise_for_status()
r.encoding = 'utf-8'
return r.text
except:
return ''
# 获取书籍信息
def get_book_info(self, url):
html = self.get_html(url)
if html:
tree = etree.HTML(html)
name = tree.xpath('//*[@id="wrapper"]/h1/span/text()')[0] # 书名
author = tree.xpath('//*[@id="info"]/span[1]/a/text()')[0] # 作者
press = tree.xpath('//*[@id="info"]/span[2]/a/text()')[0] # 出版社
date = tree.xpath('//*[@id="info"]/span[3]/text()')[0] # 出版日期
page = tree.xpath('//*[@id="info"]/span[4]/text()')[0] # 页数
price = tree.xpath('//*[@id="wrapper"]/div[2]/div/div[1]/div[1]/span[1]/text()')[0] # 价格
isbn = tree.xpath('//*[@id="info"]/span[11]/text()')[0] # ISBN号
score = tree.xpath('//*[@id="interest_sectl"]/div/div[2]/strong/text()')[0] # 豆瓣评分
num = tree.xpath('//*[@id="interest_sectl"]/div/div[2]/div/div[2]/a/span/text()')[0] # 评价人数
cover = tree.xpath('//*[@id="mainpic"]/a/img/@src')[0] # 书籍封面
info = {'name': name, 'author': author, 'press': press, 'date': date, 'page': page, 'price': price, 'isbn': isbn, 'score': score, 'num': num, 'cover': cover, 'url': url}
self.book_list.append(info)
# 获取所有书籍的URL
def get_book_urls(self, page):
url = self.base_url + '?start=' + str(page * 20) + '&type=T'
html = self.get_html(url)
if html:
tree = etree.HTML(html)
urls = tree.xpath('//ul[@class="subject-list"]/li/div[@class="info"]/h2/a/@href')
for u in urls:
self.q.put(u)
# 线程函数
def worker(self):
while not self.q.empty():
url = self.q.get()
self.get_book_info(url)
self.q.task_done()
# 启动爬虫
def start(self, thread_num=4):
# 获取所有书籍的URL
for page in range(10):
self.get_book_urls(page)
# 创建线程
for i in range(thread_num):
t = threading.Thread(target=self.worker)
t.start()
# 阻塞主线程,等待所有任务完成
self.q.join()
# 按照豆瓣评分降序保存书籍信息
self.book_list = sorted(self.book_list, key=lambda x: float(x['score']), reverse=True)
with open(self.tag + '.txt', 'w', encoding='utf-8') as f:
for book in self.book_list:
f.write('书名:' + book['name'] + '\n')
f.write('作者:' + book['author'] + '\n')
f.write('出版社:' + book['press'] + '\n')
f.write('出版日期:' + book['date'] + '\n')
f.write('页数:' + book['page'] + '\n')
f.write('价格:' + book['price'] + '\n')
f.write('ISBN号:' + book['isbn'] + '\n')
f.write('豆瓣评分:' + book['score'] + '\n')
f.write('评价人数:' + book['num'] + '\n')
f.write('书籍封面:' + book['cover'] + '\n')
f.write('URL:' + book['url'] + '\n\n')
if __name__ == '__main__':
start_time = time.time()
spider = Spider('杂文') # 爬取杂文标签下的书籍
spider.start()
end_time = time.time()
print('爬取完成,用时%.2f秒' % (end_time - start_time))
```
在上面的代码中,我们首先定义了一个Spider类,其中包含了获取页面内容、获取书籍信息、获取所有书籍的URL、线程函数、启动爬虫等方法。在启动爬虫时,我们首先获取所有书籍的URL,然后创建指定数量的线程,每个线程从URL队列中取出一个URL,获取该书籍的信息,并将信息添加到书籍列表中。在所有线程完成任务后,我们按照豆瓣评分降序保存书籍信息。
这份代码使用了多线程和xpath技术,可以爬取杂文标签下的所有书籍信息,包括书名、作者、出版社、出版日期、页数、价格、ISBN号、豆瓣评分、评价人数、书籍封面和URL,并按照豆瓣评分进行排序。如果你需要爬取其他标签下的书籍信息,只需要修改Spider类的构造函数中的tag变量即可。
阅读全文