threading.Thread多线程爬取书站
之前用threading.Thread写的多线程爬取书站的书。
需要引用的库:
import threading
import requests,os,time,random
from lxml import html
from urllib import parse
先把用到的变量列出来:
我做了个请求头的列表,随机选择请求头。
#创建Lock()给数组加锁
gLock = threading.Lock()
#公用数组,记录章节下载链接
book_link_lst = []
#公用字典保存book信息
#key:'book_name','index_link','book_path','book_files','thread_isover','code'
book_info = dict()
#创建一个头列表
user_agent_list = ["Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; …) Gecko/20100101 Firefox/61.0",
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)",
"Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.5; en-US; rv:1.9.2.15) Gecko/20110303 Firefox/3.6.15",
]
headers={
'User-Agent':random.choice(user_agent_list)}
然后,我将整个程序分成了几个函数,在需要的时间进行调用就可以了。
1.读取html的函数,使用requests读取页面内容,返回html数据
#获取html文件
def get_html(url):
code = book_info['code']
headers={
'User-Agent':random.choice(user_agent_list)}
page = requests.get(url,headers).content.decode(code)
strhtml = html.fromstring(page)
return strhtml
2.获取章节列表
根据读取的页面数据,返回各个章节的页面链接,放入一个List中。并且为了方便排序,给每个章节加上序号。返回数据是[(0,链接),(1,链接),…]
#获取章节链接返回数组[[index,连接],]
def get_booklist(strhtml):
rlst = list()
#书名写入公用字典
book_info['book_name'] = strhtml.xpath('//*[@id="info"]/h1/text()')[0]
listurls = [parse.urljoin(book_info['index_link'],i) for i in strhtml.xpath('//*[@id="list"]/dl/dd/a/@href')]
return list(zip(range(len(listurls)),listurls))
3.起始函数
将各个准备阶段的工作合在这一个函数中,读取需要记录的属性,记录进公共函数里。并且生成需要读取的章节链接列表,写入一个List,一会儿用这个List作为任务池,供多线程进行调用。
#起始函数,获取章节链接,放入公用数组
def crate_link(url,code):
#页面编码写入公用字典
book_info['code'] = code
#链接写入公用字典
book_info['index_link'] = url
#初始化结束链接数
book_info['thread_isover'] = 0
#获得索引页页面文件
page = get_html(url)
#获得章节列表
book_links = get_booklist(page)
for b in book_links:
#章节列表追加入公用列表