鱼C论坛

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

[已解决]爬虫多线程

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

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

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

x
  1. import requests
  2. import bs4
  3. import re
  4. from lxml import etree
  5. from multiprocessing import Pool


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


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

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

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

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


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

  25. def get_text(html):
  26.     tree = etree.HTML(html)
  27.     title = tree.xpath('//div[@class="bookname"]/h1/text()')[0]
  28.     f.write(title)
  29.     f.write('\n\n')
  30.     text = tree.xpath('//div[@id="content"]//text()')
  31.     for each in text:
  32.         each.replace('\xa0\xa0\xa0\xa0','\n')
  33.         print(each)
  34.         f.write(each + '\n')

  35. def get_list(url):
  36.     html = open_html(url)
  37.     content_list = []

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

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

  41.     for each in list1:
  42.         url = url_1 + each
  43.         content_list.append(url)
  44.     return content_list

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


  54.     f.close()




  55. if __name__ == "__main__":
  56.     headers = {
  57.         'Accept-Language': 'zh-CN',
  58.         'Cache-Control': 'no-cache',
  59.         'Connection': 'Keep-Alive',
  60.         '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'
  61.     }
  62.     main()
复制代码

有大佬能给指点一下我这个多线程哪用错了吗
最佳答案
2020-8-27 16:33:44
君子好逑 发表于 2020-8-27 16:17
大佬,这是我改完的代码,你看一下有没有什么能改进的地方。还有就是爬完是无序的,你有什么解决的好方 ...

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

使用道具 举报

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


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


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

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

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

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


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

  25. def get_text(url):
  26.     html = requests.get(url,headers=headers).text
  27.     tree = etree.HTML(html)
  28.     title = tree.xpath('//div[@class="bookname"]/h1/text()')[0]
  29.     print(title)
  30.     f.write(title)
  31.     f.write('\n\n')
  32.     text = tree.xpath('//div[@id="content"]//text()')
  33.     for each in text:
  34.         each.replace('\xa0\xa0\xa0\xa0','\n')
  35.         print(each)
  36.         f.write(each + '\n')

  37. def get_list(url):
  38.     html = open_html(url)
  39.     content_list = []

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

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

  43.     for each in list1:
  44.         url = url_1 + each
  45.         content_list.append(url)
  46.     return content_list

  47. def main():
  48.     catalog_address = get_mulu()
  49.     number = int(input('请输入您想获取的章节总数:'))
  50.     content_list = get_list(catalog_address)
  51.     print(len(content_list))
  52.     content_list = content_list[0:number]
  53.     for each in content_list:
  54.         print(each)
  55.     p = Pool(9)
  56.     p.map(get_text,content_list)
  57.     p.join()


  58.     f.close()




  59. if __name__ == "__main__":
  60.     headers = {
  61.         'Accept-Language': 'zh-CN',
  62.         'Cache-Control': 'no-cache',
  63.         'Connection': 'Keep-Alive',
  64.         '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'
  65.     }
  66.     main()

复制代码

代码已改好,具体改法看我的代码35-37行写代码细心点
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

这个实在之前的代码上删删改改就容易犯错
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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


还有你的部分函数功能重复
  1. def open_html(url):
  2.     res = requests.get(url=url, headers=headers)
  3.     html = res.text
  4.     return html
  5. def get_html(url):
  6.     response = requests.get(url=url, headers=headers)
  7.     html = response.text
  8.     return html
复制代码

这两个一模一样
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

大佬,这个代码在你那能运行得通吗
我这边老是报错先是这个错误提示 错1.png
我在get_text函数里粘了一遍headers后又报这个错误 错2.png
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

  6. headers = {
  7.         'Accept-Language': 'zh-CN',
  8.         'Cache-Control': 'no-cache',
  9.         'Connection': 'Keep-Alive',
  10.         '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'
  11.     }
  12. def open_html(url):
  13.     res = requests.get(url=url, headers=headers)
  14.     html = res.text
  15.     return html


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

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

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

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


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

  31. def get_text(url):
  32.     html = requests.get(url,headers=headers).text
  33.     tree = etree.HTML(html)
  34.     title = tree.xpath('//div[@class="bookname"]/h1/text()')[0]
  35.     print(title)
  36.     f.write(title)
  37.     f.write('\n\n')
  38.     text = tree.xpath('//div[@id="content"]//text()')
  39.     for each in text:
  40.         each.replace('\xa0\xa0\xa0\xa0','\n')
  41.         print(each)
  42.         f.write(each + '\n')

  43. def get_list(url):
  44.     html = open_html(url)
  45.     content_list = []

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

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

  49.     for each in list1:
  50.         url = url_1 + each
  51.         content_list.append(url)
  52.     return content_list

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



  63.     f.close()




  64. if __name__ == "__main__":
  65.     main()


复制代码

这样试一下
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

错2.png
还是报f没定义的错误提示大佬
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

  6. headers = {
  7.         'Accept-Language': 'zh-CN',
  8.         'Cache-Control': 'no-cache',
  9.         'Connection': 'Keep-Alive',
  10.         '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'
  11.     }
  12. def open_html(url):
  13.     res = requests.get(url=url, headers=headers)
  14.     html = res.text
  15.     return html


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

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

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

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


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

  31. def get_text(url):
  32.     html = requests.get(url,headers=headers).text
  33.     tree = etree.HTML(html)
  34.     title = tree.xpath('//div[@class="bookname"]/h1/text()')[0]
  35.     print(title)
  36.     global f
  37.     f.write(title)
  38.     f.write('\n\n')
  39.     text = tree.xpath('//div[@id="content"]//text()')
  40.     for each in text:
  41.         each.replace('\xa0\xa0\xa0\xa0','\n')
  42.         print(each)
  43.         f.write(each + '\n')

  44. def get_list(url):
  45.     html = open_html(url)
  46.     content_list = []

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

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

  50.     for each in list1:
  51.         url = url_1 + each
  52.         content_list.append(url)
  53.     return content_list

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


  64.     global f
  65.     f.close()




  66. if __name__ == "__main__":

  67.     main()
复制代码

建议你把用到文件的地方单独列出来,已修改f的问题
小甲鱼最新课程 -> https://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申明成全局了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

使用道具 举报

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

大佬,那个多线程pool后面跟的参数是指一次处理的进程个数,跟总共需要处理的进程个数多少没有关系是吧
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

但是我看视频上要再p.map之后加上p.close和p.join。不加的话没影响吗
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

  6. headers = {
  7.         'Accept-Language': 'zh-CN',
  8.         'Cache-Control': 'no-cache',
  9.         'Connection': 'Keep-Alive',
  10.         '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'
  11.     }
  12.    
  13. def open_html(url):
  14.     res = requests.get(url=url, headers=headers)
  15.     html = res.text
  16.     return html

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

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

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

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

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

  28. def get_text(dic):
  29.     name = dic['name']
  30.     url = dic['url']
  31.     f = open(name + '.txt','a+',encoding='utf-8')
  32.     html = requests.get(url,headers=headers).text
  33.     tree = etree.HTML(html)
  34.     title = tree.xpath('//div[@class="bookname"]/h1/text()')[0]
  35.     f.write(title)
  36.     f.write('\n\n')
  37.     text = tree.xpath('//div[@id="content"]//text()')
  38.     for each in text:
  39.         each.replace('\xa0\xa0\xa0\xa0','\n')
  40.         f.write(each + '\n')
  41.     f.write('\n\n')
  42.     f.close()
  43.     print(title,'爬取完成!!!')

  44. def get_list(url,name):
  45.     html = open_html(url)
  46.     content_list = []

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

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

  50.     for each in list1:
  51.         url = url_1 + each
  52.         dict1 = {
  53.             'name':name,
  54.             'url':url
  55.         }
  56.         content_list.append(dict1)
  57.     return content_list

  58. def main():
  59.     global name
  60.     (catalog_address,name) = get_mulu()
  61.       
  62.     number = int(input('请输入您想获取的章节总数:'))
  63.     content_list = get_list(catalog_address,name)
  64.     print(len(content_list))
  65.     content_list = content_list[0:number]
  66.     for each in content_list:
  67.         print(each)
  68.     p = Pool(9)
  69.     p.map(get_text,content_list)

  70. if __name__ == "__main__":

  71.     main()
复制代码

大佬,这是我改完的代码,你看一下有没有什么能改进的地方。还有就是爬完是无序的,你有什么解决的好方法吗
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

使用道具 举报

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

如果没有问题了,评最佳吧
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-1 20:25

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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