鱼C论坛

 找回密码
 立即注册
查看: 2256|回复: 15

[已解决]爬虫多线程

[复制链接]
发表于 2020-8-27 13:02:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
import requests
import bs4
import re
from lxml import etree
from multiprocessing import Pool


def open_html(url):
    res = requests.get(url=url, headers=headers)
    html = res.text
    return html


def get_mulu():  # 拿到小说目录的地址
    url1 = 'https://www.biduo.cc/search.php?q='
    name = input("请输入小说名:")
    global f
    f = open(name + '.txt', 'w',encoding='utf-8')
    url = url1 + name

    res = requests.get(url, headers=headers)
    s = bs4.BeautifulSoup(res.text, features="lxml")

    xiaoshuo = s.find("h3", class_="result-item-title result-game-item-title")  # 找到 第一个 标签(即为搜索榜一) 找全部可用s.find_all

    url_ = xiaoshuo.find("a").get('href')  # 在获得的标签中 继续找到 a 标签,并get 到 href 属性
    return ("https://www.biduo.cc" + url_)  # 加前缀


def get_html(url):
    response = requests.get(url=url, headers=headers)
    html = response.text
    return html

def get_text(html):
    tree = etree.HTML(html)
    title = tree.xpath('//div[@class="bookname"]/h1/text()')[0]
    f.write(title)
    f.write('\n\n')
    text = tree.xpath('//div[@id="content"]//text()')
    for each in text:
        each.replace('\xa0\xa0\xa0\xa0','\n')
        print(each)
        f.write(each + '\n')

def get_list(url):
    html = open_html(url)
    content_list = []

    regular1 = re.compile('<dd><a href="(.*?)"  >.*?</a></dd>')
    list1 = regular1.findall(html)

    url_1 = 'https://www.biduo.cc'

    for each in list1:
        url = url_1 + each
        content_list.append(url)
    return content_list

def main():
    catalog_address = get_mulu()
    number = int(input('请输入您想获取的章节总数:'))
    content_list = get_list(catalog_address)
    content_list = content_list[0:number]
    for each in content_list:
        print(each)
    p = Pool(9)
    p.map(get_text,content_list)


    f.close()




if __name__ == "__main__":
    headers = {
        'Accept-Language': 'zh-CN',
        'Cache-Control': 'no-cache',
        'Connection': 'Keep-Alive',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18363'
    }
    main()
有大佬能给指点一下我这个多线程哪用错了吗
最佳答案
2020-8-27 16:33:44
君子好逑 发表于 2020-8-27 16:17
大佬,这是我改完的代码,你看一下有没有什么能改进的地方。还有就是爬完是无序的,你有什么解决的好方 ...

多线程运行,如果把内容放在一个文件里,本身就是无序,无法避免,但可以创建多个文件来达到目的,(创建的文件多是一个缺点)比如说多线程爬取图片,就不会乱码
批注 2020-08-27 125659.png
批注 2020-08-27 1256591.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-8-27 14:27:11 | 显示全部楼层
本帖最后由 1q23w31 于 2020-8-27 14:28 编辑
import requests
import bs4
import re
from lxml import etree
from multiprocessing import Pool


def open_html(url):
    res = requests.get(url=url, headers=headers)
    html = res.text
    return html


def get_mulu():  # 拿到小说目录的地址
    url1 = 'https://www.biduo.cc/search.php?q='
    name = input("请输入小说名:")
    global f
    f = open(name + '.txt', 'w',encoding='utf-8')
    url = url1 + name

    res = requests.get(url, headers=headers)
    s = bs4.BeautifulSoup(res.text, features="lxml")

    xiaoshuo = s.find("h3", class_="result-item-title result-game-item-title")  # 找到 第一个 标签(即为搜索榜一) 找全部可用s.find_all

    url_ = xiaoshuo.find("a").get('href')  # 在获得的标签中 继续找到 a 标签,并get 到 href 属性
    return ("https://www.biduo.cc" + url_)  # 加前缀


def get_html(url):
    response = requests.get(url=url, headers=headers)
    html = response.text
    return html

def get_text(url):
    html = requests.get(url,headers=headers).text
    tree = etree.HTML(html)
    title = tree.xpath('//div[@class="bookname"]/h1/text()')[0]
    print(title)
    f.write(title)
    f.write('\n\n')
    text = tree.xpath('//div[@id="content"]//text()')
    for each in text:
        each.replace('\xa0\xa0\xa0\xa0','\n')
        print(each)
        f.write(each + '\n')

def get_list(url):
    html = open_html(url)
    content_list = []

    regular1 = re.compile('<dd><a href="(.*?)"  >.*?</a></dd>')
    list1 = regular1.findall(html)

    url_1 = 'https://www.biduo.cc'

    for each in list1:
        url = url_1 + each
        content_list.append(url)
    return content_list

def main():
    catalog_address = get_mulu()
    number = int(input('请输入您想获取的章节总数:'))
    content_list = get_list(catalog_address)
    print(len(content_list))
    content_list = content_list[0:number]
    for each in content_list:
        print(each)
    p = Pool(9)
    p.map(get_text,content_list)
    p.join()


    f.close()




if __name__ == "__main__":
    headers = {
        'Accept-Language': 'zh-CN',
        'Cache-Control': 'no-cache',
        'Connection': 'Keep-Alive',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18363'
    }
    main()
代码已改好,具体改法看我的代码35-37行写代码细心点
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-27 14:40:32 | 显示全部楼层
1q23w31 发表于 2020-8-27 14:27
代码已改好,具体改法看我的代码35-37行写代码细心点

这个实在之前的代码上删删改改就容易犯错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-27 14:42:41 | 显示全部楼层
本帖最后由 1q23w31 于 2020-8-27 14:44 编辑
君子好逑 发表于 2020-8-27 14:40
这个实在之前的代码上删删改改就容易犯错


还有你的部分函数功能重复
def open_html(url):
    res = requests.get(url=url, headers=headers)
    html = res.text
    return html
def get_html(url):
    response = requests.get(url=url, headers=headers)
    html = response.text
    return html
这两个一模一样
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-27 14:44:59 | 显示全部楼层
1q23w31 发表于 2020-8-27 14:27
代码已改好,具体改法看我的代码35-37行写代码细心点

大佬,这个代码在你那能运行得通吗
我这边老是报错先是这个错误提示 错1.png
我在get_text函数里粘了一遍headers后又报这个错误 错2.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-27 14:45:31 | 显示全部楼层
1q23w31 发表于 2020-8-27 14:42
还有你的部分函数功能重复
这两个一模一样

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-27 14:50:01 | 显示全部楼层
import requests
import bs4
import re
from lxml import etree
from multiprocessing import Pool

headers = {
        'Accept-Language': 'zh-CN',
        'Cache-Control': 'no-cache',
        'Connection': 'Keep-Alive',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18363'
    }
def open_html(url):
    res = requests.get(url=url, headers=headers)
    html = res.text
    return html


def get_mulu():  # 拿到小说目录的地址
    url1 = 'https://www.biduo.cc/search.php?q='
    name = input("请输入小说名:")
    global f
    f = open(name + '.txt', 'w',encoding='utf-8')
    url = url1 + name

    res = requests.get(url, headers=headers)
    s = bs4.BeautifulSoup(res.text, features="lxml")

    xiaoshuo = s.find("h3", class_="result-item-title result-game-item-title")  # 找到 第一个 标签(即为搜索榜一) 找全部可用s.find_all

    url_ = xiaoshuo.find("a").get('href')  # 在获得的标签中 继续找到 a 标签,并get 到 href 属性
    return ("https://www.biduo.cc" + url_)  # 加前缀


def get_html(url):
    response = requests.get(url=url, headers=headers)
    html = response.text
    return html

def get_text(url):
    html = requests.get(url,headers=headers).text
    tree = etree.HTML(html)
    title = tree.xpath('//div[@class="bookname"]/h1/text()')[0]
    print(title)
    f.write(title)
    f.write('\n\n')
    text = tree.xpath('//div[@id="content"]//text()')
    for each in text:
        each.replace('\xa0\xa0\xa0\xa0','\n')
        print(each)
        f.write(each + '\n')

def get_list(url):
    html = open_html(url)
    content_list = []

    regular1 = re.compile('<dd><a href="(.*?)"  >.*?</a></dd>')
    list1 = regular1.findall(html)

    url_1 = 'https://www.biduo.cc'

    for each in list1:
        url = url_1 + each
        content_list.append(url)
    return content_list

def main():
    catalog_address = get_mulu()
    number = int(input('请输入您想获取的章节总数:'))
    content_list = get_list(catalog_address)
    print(len(content_list))
    content_list = content_list[0:number]
    for each in content_list:
        print(each)
    p = Pool(9)
    p.map(get_text,content_list)



    f.close()




if __name__ == "__main__":
    main()
这样试一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-27 14:53:52 | 显示全部楼层

错2.png
还是报f没定义的错误提示大佬
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-27 14:57:39 | 显示全部楼层
君子好逑 发表于 2020-8-27 14:53
还是报f没定义的错误提示大佬
import requests
import bs4
import re
from lxml import etree
from multiprocessing import Pool

headers = {
        'Accept-Language': 'zh-CN',
        'Cache-Control': 'no-cache',
        'Connection': 'Keep-Alive',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18363'
    }
def open_html(url):
    res = requests.get(url=url, headers=headers)
    html = res.text
    return html


def get_mulu():  # 拿到小说目录的地址
    url1 = 'https://www.biduo.cc/search.php?q='
    name = input("请输入小说名:")
    global f
    f = open(name + '.txt', 'w',encoding='utf-8')
    url = url1 + name

    res = requests.get(url, headers=headers)
    s = bs4.BeautifulSoup(res.text, features="lxml")

    xiaoshuo = s.find("h3", class_="result-item-title result-game-item-title")  # 找到 第一个 标签(即为搜索榜一) 找全部可用s.find_all

    url_ = xiaoshuo.find("a").get('href')  # 在获得的标签中 继续找到 a 标签,并get 到 href 属性
    return ("https://www.biduo.cc" + url_)  # 加前缀


def get_html(url):
    response = requests.get(url=url, headers=headers)
    html = response.text
    return html

def get_text(url):
    html = requests.get(url,headers=headers).text
    tree = etree.HTML(html)
    title = tree.xpath('//div[@class="bookname"]/h1/text()')[0]
    print(title)
    global f
    f.write(title)
    f.write('\n\n')
    text = tree.xpath('//div[@id="content"]//text()')
    for each in text:
        each.replace('\xa0\xa0\xa0\xa0','\n')
        print(each)
        f.write(each + '\n')

def get_list(url):
    html = open_html(url)
    content_list = []

    regular1 = re.compile('<dd><a href="(.*?)"  >.*?</a></dd>')
    list1 = regular1.findall(html)

    url_1 = 'https://www.biduo.cc'

    for each in list1:
        url = url_1 + each
        content_list.append(url)
    return content_list

def main():
    catalog_address = get_mulu()
    number = int(input('请输入您想获取的章节总数:'))
    content_list = get_list(catalog_address)
    print(len(content_list))
    content_list = content_list[0:number]
    for each in content_list:
        print(each)
    p = Pool(9)
    p.map(get_text,content_list)


    global f
    f.close()




if __name__ == "__main__":

    main()
建议你把用到文件的地方单独列出来,已修改f的问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-27 15:04:21 | 显示全部楼层
1q23w31 发表于 2020-8-27 14:57
建议你把用到文件的地方单独列出来,已修改f的问题


错1.png
大佬,你的意思是在那个get_text里面打开关闭文件吗。我忽然有个点子大佬,如果我进get_text函数的时候如果检测到文件存在,就追加,文件不存在就新建行不行。或者在main里面新建一个文件后直接关闭,以后在get_text里面直接追加内容是不是就不用把f用global申明成全局了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-27 15:11:21 | 显示全部楼层
文件操作最好是集中到一个函数里面,不然你其他地方用到这个文件,还得声明一下,你说的在get_text里检测的方法也行,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-27 15:54:16 | 显示全部楼层
1q23w31 发表于 2020-8-27 15:11
文件操作最好是集中到一个函数里面,不然你其他地方用到这个文件,还得声明一下,你说的在get_text里检测的 ...

大佬,那个多线程pool后面跟的参数是指一次处理的进程个数,跟总共需要处理的进程个数多少没有关系是吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-27 15:56:06 | 显示全部楼层
1q23w31 发表于 2020-8-27 15:11
文件操作最好是集中到一个函数里面,不然你其他地方用到这个文件,还得声明一下,你说的在get_text里检测的 ...

但是我看视频上要再p.map之后加上p.close和p.join。不加的话没影响吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-27 16:17:24 | 显示全部楼层
1q23w31 发表于 2020-8-27 15:11
文件操作最好是集中到一个函数里面,不然你其他地方用到这个文件,还得声明一下,你说的在get_text里检测的 ...
import requests
import bs4
import re
from lxml import etree
from multiprocessing import Pool

headers = {
        'Accept-Language': 'zh-CN',
        'Cache-Control': 'no-cache',
        'Connection': 'Keep-Alive',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18363'
    }
    
def open_html(url):
    res = requests.get(url=url, headers=headers)
    html = res.text
    return html

def get_mulu():  # 拿到小说目录的地址
    url1 = 'https://www.biduo.cc/search.php?q='
    name = input("请输入小说名:")

    f = open(name + '.txt', 'w',encoding='utf-8')
    f.close()
    url = url1 + name

    res = requests.get(url, headers=headers)
    s = bs4.BeautifulSoup(res.text, features="lxml")

    xiaoshuo = s.find("h3", class_="result-item-title result-game-item-title")  # 找到 第一个 标签(即为搜索榜一) 找全部可用s.find_all

    url_ = xiaoshuo.find("a").get('href')  # 在获得的标签中 继续找到 a 标签,并get 到 href 属性
    return ("https://www.biduo.cc" + url_,name)  # 加前缀

def get_text(dic):
    name = dic['name']
    url = dic['url']
    f = open(name + '.txt','a+',encoding='utf-8')
    html = requests.get(url,headers=headers).text
    tree = etree.HTML(html)
    title = tree.xpath('//div[@class="bookname"]/h1/text()')[0]
    f.write(title)
    f.write('\n\n')
    text = tree.xpath('//div[@id="content"]//text()')
    for each in text:
        each.replace('\xa0\xa0\xa0\xa0','\n')
        f.write(each + '\n')
    f.write('\n\n')
    f.close()
    print(title,'爬取完成!!!')

def get_list(url,name):
    html = open_html(url)
    content_list = []

    regular1 = re.compile('<dd><a href="(.*?)"  >.*?</a></dd>')
    list1 = regular1.findall(html)

    url_1 = 'https://www.biduo.cc'

    for each in list1:
        url = url_1 + each
        dict1 = {
            'name':name,
            'url':url
        }
        content_list.append(dict1)
    return content_list

def main():
    global name
    (catalog_address,name) = get_mulu()
       
    number = int(input('请输入您想获取的章节总数:'))
    content_list = get_list(catalog_address,name)
    print(len(content_list))
    content_list = content_list[0:number]
    for each in content_list:
        print(each)
    p = Pool(9)
    p.map(get_text,content_list)

if __name__ == "__main__":

    main()
大佬,这是我改完的代码,你看一下有没有什么能改进的地方。还有就是爬完是无序的,你有什么解决的好方法吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-27 16:33:44 | 显示全部楼层    本楼为最佳答案   
君子好逑 发表于 2020-8-27 16:17
大佬,这是我改完的代码,你看一下有没有什么能改进的地方。还有就是爬完是无序的,你有什么解决的好方 ...

多线程运行,如果把内容放在一个文件里,本身就是无序,无法避免,但可以创建多个文件来达到目的,(创建的文件多是一个缺点)比如说多线程爬取图片,就不会乱码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-28 15:00:29 | 显示全部楼层
君子好逑 发表于 2020-8-27 16:17
大佬,这是我改完的代码,你看一下有没有什么能改进的地方。还有就是爬完是无序的,你有什么解决的好方 ...

如果没有问题了,评最佳吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-11 06:14

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表